《JavaScript高級程序設計》中涉及到的繼承方式:原型鏈,借用構造函數,組合繼承,原型式繼承,寄生式繼承,寄生組合式繼承。函數
不要緊,我當時看完第一遍也是實力懵逼。後來反反覆覆學了好多遍,總算搞清楚了(特別是寄生組合式繼成。)接下來就儘可能用淺顯易懂的方式總結一遍。測試
一.原型鏈:this
原型我就不過多介紹了,有時間會寫博客總結。prototype
先說說重寫原型對象。什麼是重寫原型對象?就是以對象字面量的形式來從新定義原型對象的屬性和方法。設計
好比:指針
function Person{ } Person.prototype = { name : "Nico", age : 20, job : "FE", sayName : function(){ alert(this.name); } }
以上以對象字面量重寫原型對象以後,原型對象的constructor再也不指向Person了。由於每建立一個函數,就會同時建立它的prototype對象,這個對象也自動得到constructor屬性,所以,新的原型對象的constructor如今指向Object構造函數,能夠經過constructor:Person這麼一句加強對象。不過這樣會將它的[[Enumerable]]特性設置爲true,能夠經過Object.defineProperty()來設置。具體就不作擴展了。code
這裏特意提到是由於要告訴米娜桑,若是建立實例以後從新了原型對象,實例仍指向最初的原型對象。因此實例使沒法調用新添加的方法和屬性的。因此,在經過原型鏈實現繼承時,不能使用對象字面量建立原型方法。對象
好了繼續說原型鏈繼承。實現方式是讓原型對象等於另外一個類型的實例。結果會怎樣?此時的原型對象包含指向另外一個原型的指針[[prototype]],相應地,另外一個原型中也包含着一個指向另外一個構造函數的指針constructor。如此以來層層遞進,構成了實例與原型的鏈條。繼承
先看一個例子。ip
function superType(){ this.property = true; } superType.prototype.getSuperValue = function(){ return this.property; } function subType(){ this.subproperty = false; } //繼承了superType subType.prototype = new superType(); subType.prototype.getSubValue = function(){ return this.subProperty; } var instance = new subValue(); alert(instance.getSuperValue);
以上的代碼沒有使用subType默認提供的原型,而是給它換了一個新原型,即superType的實例。如此一來,superType的全部的實例屬性和實例方法被添加到subType的原型對象之中,由於此時subType的原型是superType的實例,因此實例屬性和方法天然而然會被添加到實例之中。subType的原型對象也會多出一個[[prototype]]屬性指向superType,這樣造成一個原型鏈,實例instance訪問getSuperType()方法時,會通過三個步驟:(1)搜索實例,(2)搜索subType.prototype,(3)搜索superType.prototype。搜索過程是一環一環前行到原型鏈末端纔會停下來。(注意,instance.constructor如今指向的是superType,由於subType的原型指向了另外一個對象——superType的原型,而superType的原型的constructor指向的是superType。)
二.別忘記默認的原型:
全部函數的默認原型都是Object的實例,所以默認原型都會包含一個內部指針,指向Object.prototype。
三.肯定原型和實例的關係:
1>使用instanceof()操做符。只要用這個操做符來測試實例與原型鏈中出現過的構造函數,結果就會返回true。
alert(instance instanceof Object) //true alert(instance instanceof superType) //true alert(instance insatanceof subType) //true
2>使用isPrototypeOf()方法。只要是原型鏈中出現過的原型,均可以說是該原型鏈所派生的實例的原型。
alert(Object.prototype.isPrototypeOf(instance)) //true alert(superType.prototype.isPrototypeOf(instance)) //true alert(subType.prototype.isPrototypeOf(instance)) //true
四.原型鏈的問題
1>包含引用類型值的原型屬性會被全部實例共享。
2>在建立子類型的實例時,不能向超類型的構造函數中傳遞參數。