溫故而知新 XDes6
__proto__
),指向構造函數的原型對象(因此能夠在構造函數的 prototype 裏存放實例公用的方法)。__proto__
),若找到,則 return 該屬性值;若沒找到,繼續搜索原型的原型...給出父類 Animal,實現子類Cat:函數
function Animal (name) { this.name = name this.brother = 'Tony' } Animal.prototype.eat = function (thing) { console.log(this.name + ' eat ' + thing); }
function Cat (name) { Animal.call(this,name) // 借用構造函數,繼承父類屬性 this.sister = 'May' } Cat.prototype = new Animal() // 原型鏈,繼承父類方法 /* 在prototype繼承了父類實例的所有屬性,存在冗餘。屬性的繼承已經在構造函數內經過調用父類構造函數實現。 實際上,子類的prototype須要的只是父類實例中指向父類原型的內部指針: Cat.prototype.__proto__ = Animal.protype */ console.log(Cat.prototype) // {name: undefined(冗餘), brother: "Tony"(冗餘), constructor: ƒ} Cat.prototype.constructor = Cat // 因爲上面 Cat.prototype 進行了賦值,因此須要從新指定其構造函數。 // 這一步對 instanceof 無影響,由於 "instanceof 運算符用來測試一個對象在其原型鏈中是否存在一個構造函數的 prototype 屬性" ;影響的是Cat實例的constructor 屬性。 // 若是不作這一步:var Tom = new Cat('Tom'); Tom.constructor ==> Animal
function Cat (name) { Animal.call(this,name) this.sister = 'May' } function createObject (obj) { /* 建立一個新對象,使用現有的對象來提供新建立的對象的__proto__ ,至關於 Object.create() */ function F () {} F.prototype = obj return new F() } Cat.prototype = createObject (Animal.prototype) // 至關於 Cat.prototype = Object.create(Animal.prototype) console.log(Cat.prototype) // {constructor: ƒ} Cat.prototype.constructor = Cat
class Animal { constructor(name){ this.name = name this.brother = 'Tony' } eat(thing) { console.log(this.name + ' eat ' + thing); } } class Cat extends Animal { constructor(name) { super(name) /* super()表示調用父類構造函數,this指向子類。只有調用super以後,纔可使用this關鍵字,不然新建實例時會報錯。*/ /* 另:super做爲對象時,在普通方法中,指向父類的原型對象;在靜態方法中,指向父類。經過super調用父類方法時,方法內部this指向子類;對super的猴哥屬性賦值時,super就是this,賦值的屬性會變成子類實例的屬性 (不清楚裏面是什麼魔法)*/ this.sister = 'May' } }