javascript
创建函数查找上级_一文秒懂JavaScript中对象的7种创建方式
1.工廠模式
javascript 代碼
工廠模式:能根據(jù)接受的參數(shù)來創(chuàng)建出一個person對象.也可以無數(shù)次的調(diào)用這個函數(shù),每次都會返回一個包含3個屬性和1個方法的對象.
工廠模式雖然解決了創(chuàng)建多個相似對象的問題,但卻沒有解決對象識別的問題(即怎樣知道一個對象的類型).
2.構(gòu)造函數(shù)模式
javascript 代碼
構(gòu)造函數(shù)模式:創(chuàng)建對象要使用new關(guān)鍵字.編碼規(guī)范要求把構(gòu)造函數(shù)首字母大寫以示區(qū)分.還有什么和工廠模式不一樣的呢?
沒有顯示的創(chuàng)建對象
直接將屬性值和方法賦值給了this對象
沒有return語句
可以通過 instanceof 操作符來檢測對象類型
使用new關(guān)鍵字創(chuàng)建一個對象發(fā)生了以下4個步驟
1.創(chuàng)建一個新的對象 2.將構(gòu)造函數(shù)的作用域賦給新對象(即this指向這個新對象) 3.執(zhí)行構(gòu)造函數(shù)中的代碼 4.返回這個新對象通過圖片結(jié)果可以看到,people1和people2雖然是兩個不同的對象,但各自的constructor屬性卻相同(即具有相同的構(gòu)造函數(shù)).
構(gòu)造函數(shù)模式的不足:每一個方法都要在實例上重新創(chuàng)建一遍.people1和people2都有一個名為speakName的方法,它們相同嗎
可以看到,結(jié)果為false,說明構(gòu)造函數(shù)模式創(chuàng)建的不同實例的同名函數(shù)是不一樣的.
3.原型模式
javascript 代碼
在原型模式中,我把所有的屬性和方法全都寫在了prototype中.我們創(chuàng)建的每一個函數(shù)都有一個prototype屬性,prototype屬性是一個指針,
指向一個原型對象,這個對象中包含了所有共享的屬性和方法.所以可以看到新建出來的兩個實例的方法是完全一樣的,因為他們不屬于實例函數(shù),而是原型函數(shù).
如果現(xiàn)在給people1新增加一個speakName方法,結(jié)果又會如何呢?
可以看到,現(xiàn)在結(jié)果是false了,因為現(xiàn)在people1的speakName方法覆蓋了Prototype上的同名方法.在JS中,代碼讀取到某個對象的屬性時,先在對象實例中查找有沒有該屬性
如果找到了,則返回該屬性的值,如果沒有找到則到Prototype上去查找.這就是為什么實例會共享Prototype上屬性和方法的原因.如果想要重新訪問Prototype中的屬性可以
使用delete操作符來刪除實例中的屬性.
需要注意的一點有:原型鏈具有動態(tài)性,我們對原型對象所做的任何修改都會立即從實例上反映出來.即使是先創(chuàng)建了實例,后修改原型也是如此.如圖
可以看到,我先創(chuàng)建的對象people1和people2,即使后修改原型對象上的方法或增加一個方法,對象上的方法也跟著改變了并且新增加的方法也可以正常的訪問到,
而且兩個構(gòu)造出來的對象的方法都被改變了.
但要注意的是:如果這里重寫整個原型對象,那情況就不一樣了.
可以看到,這里我重寫了原型對象,但是卻發(fā)現(xiàn)people1的speakName方法并沒有改變,而且也不能訪問到新增加的speakAge方法.報錯說not a function.這又是為什么呢?
還是上面說到的,新創(chuàng)建一個對象時,會自動獲得一個constructor屬性指向創(chuàng)建該對象的原型對象,而這里把原型對象修改為另一個對象時也就切斷了構(gòu)造函數(shù)與最初原型的聯(lián)系.
即原先創(chuàng)建的對象引用的依然是最初的原型.
原型模式的缺點:省略了傳遞參數(shù),導(dǎo)致所有的實例在默認情況都取得相同的屬性值.當然這還不算原型模式最大的缺點,最大的缺點是,所有屬性都被全部實例所共享,這對于方法是
非常合適的,對包含基本值的屬性也沒多大的影響,只是重寫覆蓋后會在原型上留下無用的屬性.然而,對于包含引用類型值的屬性來說,問題就比較突出了.看下面的例子.
javascript 代碼
可以看到,由于friends存在于People.prototype中,所以通過people1對friends的修改也會反映在別的實例中,這就是不單獨使用原型模式的原因.
4.組合使用構(gòu)造函數(shù)模式和原型模式
javascript代碼
組合使用構(gòu)造函數(shù)模式和原型模式:創(chuàng)建自定義類型的最常見方式,用構(gòu)造函數(shù)模式來定義實例屬性,原型模式來定義共享屬性和方法.這樣,每一個實例
都有自己的實例屬性的副本,但同時又共享著對方法的引用,最大限度的節(jié)省了內(nèi)存,而且這種混合模式還支持向構(gòu)造函數(shù)傳遞參數(shù),可謂集兩家之長.
通過結(jié)果可以看見,現(xiàn)在people1對friends操作就不會影響別的對象了.
5.動態(tài)原型模式
javascript 代碼
動態(tài)原型模式:它把所有的信息都封裝在了構(gòu)造函數(shù)中,僅在某個必要的方法是否存在來決定是否初始化原型.在這個例子中,只有當sayName方法不存在的時候才會將它添加到原型中.這段代碼只會在初次調(diào)用構(gòu)造函數(shù)才會執(zhí)行,此后,原型已經(jīng)初始化,不需要再做什么修改了.
6.寄生構(gòu)造函數(shù)模式
javascript 代碼
寄生構(gòu)造函數(shù)模式:基本思想是創(chuàng)建一個函數(shù),該函數(shù)的作用僅僅是封裝創(chuàng)建對象的代碼,然后返回新創(chuàng)建的對象.除了使用了
new操作符以外,這個模式和第一種工廠模式其實是一模一樣的.
這個模式可以在特殊的情況下為對象創(chuàng)建構(gòu)造函數(shù).比如我們想創(chuàng)建一個具有額外方法的特殊數(shù)組,由于不能直接修改Array
的構(gòu)造函數(shù),因此可以使用這個模式.
javascript 代碼
結(jié)果如下:
關(guān)于寄生構(gòu)造函數(shù),有一點需要注意.返回的對象和構(gòu)造函數(shù)或構(gòu)造函數(shù)的原型屬性之間都沒有關(guān)系,也就是說,不能通過instanceof來
確定對象的類型.所以在能使用其它模式的情況下盡量不要使用此種模式
7.穩(wěn)妥構(gòu)造函數(shù)模式.
javascript 代碼
穩(wěn)妥構(gòu)造函數(shù)模式:在以這種模式創(chuàng)建的對象中,除了使用speakName方法外沒有其它辦法訪問name的值.這樣創(chuàng)建的對象叫作穩(wěn)妥對象.
穩(wěn)妥模式提供的這種安全性,使得它非常適合在某些安全環(huán)境——例如,ADsafe(http://www.adsafe.org)和Caja(http://code.google.com/p/google-caja/)提供的環(huán)境——
下使用。(與寄生構(gòu)造函數(shù)模式類似,這種模式創(chuàng)建的對象和構(gòu)造函數(shù)之間也沒有聯(lián)系,也不能通過Instanceof來確定對象的類型)
有錯誤,歡迎大家指出,評論轉(zhuǎn)發(fā)哦~
《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的创建函数查找上级_一文秒懂JavaScript中对象的7种创建方式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 只导表前10条数据_【205期】面试官:
- 下一篇: js除法与C语言除法,JS算术运算符及用