<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
在JavaScript中,每一個建構函式都有一個原型,這個原型中有一個屬性constructor
會再次指回這個建構函式,這個建構函式所創造的範例物件,會有一個指標(也就是我們說的隱式原型__proto__
或者是瀏覽器中顯示的[[Prototype]]
)指向這個建構函式的原型物件。如果說該建構函式的原型物件也是由另外一個建構函式所創造的範例,那麼該建構函式的原型物件也會存在一個指標指向另外一個建構函式的原型物件,周而復始,就形成了一條原型鏈。 最特別的是所有的沒有經過再繼承函數都是由Function
範例化來的,所有的除了函數外的物件都是由Object
範例化來的,其中Object
也是由Function
範例化來的,但是Object.prototype.__proto__ === null
是成立的。
再強調一遍:原型鏈是沿著物件的隱式原型一層層的去尋找的,找到的是建構函式所創造的範例。例如下:
這個就是相當於由Student
new 出來的範例s
,查詢自身的 name
屬性,然後沿著原型鏈查詢,找到Student
中的prototype
當中,然後找到了name
這個屬性。
而這個例子,由紅框框起來的程式碼(寄生繼承的關鍵程式碼),代替註釋掉的部分,最終s
是找不到name
屬性的,這是因為紅框中的程式碼,僅僅是將Student
的隱式原型指向了Person
的顯示原型物件,未能建立任何的範例,當然就不會存在屬性這個說法。
原型鏈的問題主要有兩個方面,第一個問題是,當原型中出現包含參照值(比如陣列)的時候,所有在這條原型鏈中的範例會共用這個屬性,造成“一發而動全身”的問題。第二個問題就是子類在範例化時,不能夠給父類別型的建構函式傳參,即
無法在不影響所有物件範例的情況下把引數傳遞進父類別型的建構函式傳參
function SuperType() { this.friends = ['張三','李四'] } function SubType() { SuperType.call(this); } const p1 = new SubType(); p1.friends.push('王武'); const p2 = new SubType(); console.log(p2.friends); // ['張三','李四', '王武']
盜用建構函式實現繼承在這個例子中有了充分的體現: 首先在子類別建構函式中呼叫父類別的建構函式。因為畢竟函數就是特定上下文中執行程式碼的簡單物件,所以可以使用call()
方法以建立的物件為上下文執行的建構函式。
盜用建構函式的主要問題,也是建立物件的幾種方式中建構函式模式自定義型別的問題:必須在建構函式中定義方法,造成記憶體浪費。另外,子類也不能存取父類別原型上定義的方法,因此,盜用建構函式也不會單獨使用。
組合繼承也稱為偽經典繼承,綜合了原型鏈和建構函式,將兩者的有點結合起來。基本的思路就是使用原型鏈繼承原型上的屬性和方法,而通過盜用建構函式繼承實現範例的屬性。這樣就可以把方法定義在原型上實現複用,又可以讓每個範例有自己的屬性。
function SuperType(name) { this.name = name; this.friends = ['張三','李四']; } SuperType.prototype.sayName = function() { console.log(this.name) } // 繼承方法 SubType.prototype = new SuperType(); function SubType(name, age) { SuperType.call(this, name); this.age = age; } const p1 = new SubType('趙六', 12); const p2 = new SubType('趙六2', 22); // 建立的 p1 和 p2 能夠擁有自己的屬性並且參照值屬性也是獨立的,此外,每一個範例能夠公用父類別的方法。
組合繼承已經接近完美了,但是,我們發現,實現組合繼承就要呼叫兩次父類別建構函式。在本質上,子型別最終是要包含超類物件的所有範例屬性,子類建構函式只要在執行時重寫自己的原型就行了,這就為減少一次呼叫父類別建構函式提供了思路。
const person = { name: 'zs', friends: ['ls','ww'] } // 創造出一個範例,這個範例的隱式原型指向 person const anotherPerosn = Object.create(person); anotherPerosn.name = 'xm' anotherPerosn.friends.push('zl') console.log(anotherPerosn.name) // xm console.log(anotherPerosn.friends) // ['ls','ww', 'zl']; const anotherPerosn2 = Object.create(person); anotherPerosn.name = 'xh' anotherPerosn.friends.push('dd') console.log(anotherPerosn2.name) // xh console.log(anotherPerosn2.friends) // ['ls','ww', 'zl', 'dd'];
對於原型鏈繼承就不再過多的解釋了。。。。
寄生式繼承與原型式繼承比較相似,都會存在屬性參照值共用的問題。
function createAnotherPerson(original) { const clone = Object.create(original); //通過呼叫函數建立一個新的物件 clone.sayHi = function() { // 以某種方式增強這個物件 console.log('Hi'); } return clone; }
寄生式繼承,不僅存在著屬性參照值共用的問題而且函數還不能進行復用。
// 實現了寄生式組合繼承的核心邏輯 function inheritPrototype(subFn, parentFn){ subFn.prototype = Object.create(parentFn.prototype); // 建立賦值物件 Object.defineProperty(subFn.prototype,'constructor', { // 增強物件 enumerable: false, writable: false, configurable: false, value: subFn, }) } function Person(name, age, address) { this.name = name; this.age = age; this.address = address; } Person.prototype.eating = function() { console.log(this.name + "正在吃飯"); } // 共用方法 function Student(name, age, address, sno) { Person.call(this, name, age, address); // 繫結 this 確保建立出來的物件是相互獨立的 this.sno = sno; this.studing = function() { console.log(`${this.name}正在學習`) } } function Teacher(name, age, address, tno) { Person.call(this, name, age, address) this.tno = tno; }
寄生+組合式(建構函式+原型鏈)完美的解決了其他繼承出現的問題。
到此這篇關於JavaScript原型鏈及常見的繼承方法的文章就介紹到這了,更多相關JS原型鏈內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援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