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