JavaScript原型和繼承

weixin_33766168發表於2015-09-15

《JavaScript高階程式設計 第三版》 學習筆記
Object-Oriented 有一個標誌,就是都有類的概念,通過類來建立多個具有相同屬性和方法的物件。而對於 EMCAScript中沒有類的概念,ECMA-262把物件定義為
”無序屬性的集合,該屬性可以包含任何基本值,物件或者函式。“

原型模式

  • 每個函式都有一個prototype(原型)屬性

  • 這個屬性都有一個指標,指向一個物件

  • 這個物件包含由特定型別所有例項共享的屬性和方法

  • 使用原型的好處是 可以讓所有物件例項共享它包含的方法和屬性

通過in操作符和hasOwnProperty來判斷給定屬性是來自於原型還是例項
in- true 代表屬性在物件中存在 來自例項或者來自原型
hasOwnProperty- true代表屬性來自於例項 是例項屬性

繼承

ECMAScript中只支援實現繼承,而且是通過原型鏈的方式來實現的

理解原型物件
是這樣的
當我們建立一個新函式的時候,會根據一組特定的規則為該函式建立一個prototype屬性,這個prototype屬性指向函式的原型物件。在預設情況下,原型物件都會自動獲得一個constructor(建構函式)屬性,這個屬性包含包含一個指向prototype屬性所在函式的指標。
所以關係就是
比如有一個Person的物件
Person.prototype => 原型物件
原型物件.constructor => Person
即 Person.prototype.constructor == Person
見下圖關係

將原型鏈作為實現繼承的主要方法,基本思想是利用原型讓一個引用型別繼承另一個引用型別的屬性和方法。
demo程式碼

function SuperType(){
    this.property = true;
}
SuperType.prototype.getSuperValue = function(){
    return this.property;
}

function SubType(){
    this.subproperty = false;
}
//SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function(){
    return this.subproperty;
}

// 繼承SuperType 就指向了SuperType的原型物件了
SubType.prototype = new SuperType();
var instance = new SubType();
alert(instance.getSuperValue()); // true
alert(instance.property); //true

<iframe width="100%" height="300" src="http://jsfiddle.net/JimWang/dmkLmnhL/embedded/&quot; allowfullscreen="allowfullscreen" frameborder="0"></iframe>

如果把SubType中的subproperty改成property會是怎麼樣呢 都會變成false

demo圖解

備註:
之所以 SuperType中property屬性會出現在,SubType.prototype中,是因為property是一個例項屬性,而SubType.prototype是SuperType的一個例項物件,所以property屬性會出現在SubType.prototype中,但是這個property相對於instance(SubType的一個例項)卻又是一個原型屬性,所以如果將subproperty換成property的話,在return this.property時,優先找到例項屬性中有這麼一個屬性,就會返回例項屬性。
此外這裡SubType.prototype.constructor 被重寫了,instance.constructor指向了SuperType 看圖
instance.getSuperValue() 這個搜尋的過程
1) 搜尋例項
2) 搜尋SubType.prototype
3) 搜尋SuperType.prototype
搜尋總是一步步向前到原型鏈末端停止(Object)

相關文章