<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
我們在前一篇文章《JS精粹,原型鏈繼承和建構函式繼承的 “毛病”》 ,提到了:原型鏈繼承、建構函式繼承、組合繼承;
在另一篇文章《驀然回首,“工廠、構造、原型”設計模式,正在燈火闌珊處》,提到了:我們用於建立物件的三種設計模式:工廠設計模式、構造設計模式、原型設計模式;
至此,我們可以明顯的感受到:JS 要實現物件導向(繼承的能力),離不開這 3 種設計模式;
原型鏈 + 建構函式 = 組合繼承
本篇帶來一個新的繼承方式:寄生繼承,它由工廠模式和建構函式模式組成,即
工廠+建構函式 = 寄生繼承
正是由於:原型鏈繼承和建構函式繼承的 “毛病”
組合繼承應運而生:
function SuperType(name){ this.name = name; this.colors = ["red", "blue", "green"]; } function SubType(name, age){ SuperType.call(this, name) // 建構函式繼承 (兩次呼叫父類別建構函式) this.age = age; } SuperType.prototype.sayName = function() { console.log(this.name); } SubType.prototype = new SuperType() // 原型鏈繼承 (一次呼叫父類別建構函式) SubType.prototype.sayAge = function() { console.log(this.age); } let s1 = new SubType("Nicholas", 29) let s2= new SubType("Greg", 27) s1.colors.push("yellow") console.log(s1.colors) // ['red', 'blue', 'green', 'yellow'] console.log(s2.colors) // ['red', 'blue', 'green'] s1.sayName() // Nicholas s2.sayName() // Greg s1.sayAge() // 29 s2.sayAge() // 27
但是呢?這樣做,會有效率問題,父類別建構函式始終會被呼叫兩次:一次是在子類建構函式中呼叫,另一次在是建立子類原型時呼叫。
本質上,子類原型最終是要包含超類物件的所有範例屬性,子類建構函式只要在執行時重寫自己的原型就行了。
這個時候有一個新的思路!
不通過呼叫父類別建構函式給子類原型賦值,而是取得父類別原型的一個副本。使用寄生式繼承來繼承父 類原型,然後將返回的新物件賦值給子類原型。
核心程式碼是:通過工廠的方式,增強一個新物件:
function createAnother(original){ let clone = Object(original); // 通過呼叫函數建立一個新物件 clone.sayHi = function() { // 以某種方式增強這個物件 console.log("hi"); }; return clone; // 返回這個物件 }
將組合程式碼改造一下,完整程式碼是:
function inheritPrototype(subType, superType) { let prototype = Object(superType.prototype); // 建立物件 prototype.constructor = subType; // 增強物件 subType.prototype = prototype; // 賦值物件 } function SuperType(name) { this.name = name; this.colors = ["red", "blue", "green"]; } function SubType(name, age) { SuperType.call(this, name); // 建構函式繼承(只調了一次) this.age = age; } SuperType.prototype.sayName = function() { console.log(this.name); }; inheritPrototype(SubType, SuperType); // 寄生繼承 SubType.prototype.sayAge = function() { console.log(this.age); }; let s1 = new SubType("Nicholas", 29) let s2= new SubType("Greg", 27) s1.colors.push("yellow") console.log(s1.colors) // ['red', 'blue', 'green', 'yellow'] console.log(s2.colors) // ['red', 'blue', 'green'] s1.sayName() // Nicholas s2.sayName() // Greg s1.sayAge() // 29 s2.sayAge() // 27
這裡只呼叫了一次 SuperType 建構函式,避免了 SubType.prototype 上不必要也用不到的屬性;而且,原型鏈仍然保持不變,instanceof 操作符和 isPrototypeOf() 方法正常有效。
寄生式組合繼承可以算是【參照型別】繼承的最佳模式
os:不過這裡的增強寫法,理解起來真是怪,為什麼父類別的顯示原型的建構函式等於子類?
SuperType.prototype.constructor=== SubType // true
大概是為了,通過寄生實現:父類別、子類都由同一函數構造;
SubType === SubType.prototype.constructor // true SuperType.prototype.constructor === SubType.prototype.constructor // true
只要是寫 JS 的繼承,一定離不開:工廠、構造、原型設計模式;
原型鏈 + 建構函式 = 組合繼承
工廠+建構函式 = 寄生繼承;
組合繼承和寄生繼承是最常用的兩種繼承方式。
......
u1s1,class 出來前,寫 JS 實現繼承,是真滴麻煩QAQ
以上就是JS繼承與工廠構造及原型設計模式詳解的詳細內容,更多關於JS繼承與設計模式的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45