ES5中物件的繼承
阿新 • • 發佈:2020-10-12
1.繼承的型別
在oo語言中,繼承有兩種方式,藉口繼承和實現繼承,因為ECMAScript不支援方法簽名,所以ECMAScript只支援實現繼承。
2.原型鏈繼承的實現
2.1.原型鏈
ES5繼承可以使用原型鏈,原型鏈的形態可以理解為讓一個建構函式的原型成為另一個建構函式的例項,這樣會重寫這個原型物件。因為有constructor,prototype的存在,使建構函式和原型有了雙向確定的能力和範圍延展的能力,層層延伸便構成了原型鏈。
function SuperType(){ this.prototype = true; } SuperType.prototype.getSuperValue(){return this.prototype; } function SubType(){ this.subprototype = false; } Subtype.prototype = new SuperType();//實現繼承,重寫原型物件,包括constructor,現在constructor指向SuperType var instance = new Subtype(); alert(instance.getSuperValue()); //true
當訪問一個例項屬性時,先搜尋例項,再搜尋原型物件,如果還沒有找到,再向原型鏈繼續向上搜尋,在原型鏈的最頂端,君臨著Object,所有函式的預設原型都是Object的例項。
2.2.例項與原型的關係
我們可以使用instanceof操作符或者isPrototypeOf()方法來判斷原型鏈中是否出現過某建構函式。(判斷建構函式是否在原型鏈上)
alert(instance instanceof Object) //true alert(instance instanceof Supertype)//true
alert(Object.prototype.isPrototypeOf(instance));//true alert(SuperType.prototype.isPrototypeOf(instance));//true
與使用原型模式建立物件時類似,我們使用原型鏈繼承時,原型裡面的所有屬性都會被例項所共享,在創造原型鏈時,一個物件的原型會變成另一個物件的例項,所以這個例項的屬性便會被共享。
在操作繼承過來的屬性時,相當於在操作原型裡面的內容。這就像一個沒有上鎖的箱子,任何人都可以開啟。並且在使用原型鏈繼承時,我們不能向超型別的建構函式傳遞引數。
3.建構函式繼承
3.1.借用建構函式
因為原型鏈繼承有以上缺點,我們用其他方式來繼承比較好,建構函式繼承利用函式的作用域克服了原型鏈繼承中共享的問題,但是因為方法都是寫在建構函式裡的,因此不能實現方法複用。
function SuperType(){ this.colors = ["red","blue","green"]; } function SubType(){ SuperType.call(this); //在SubType作用域中執行SuperType的建構函式,實現了繼承 } var instance1 = new SubType(); instance1.colors.push("black"); alert(instance.colors);//"red, blue,green,black" var instance2 = new SubType(); alert(instance2.colors);//"red, blue,green"
4.組合繼承
在物件的建立中也出現過,我們可以結合建構函式和原型鏈來實現繼承,建構函式實現對屬性的繼承,原型鏈實現對方法的繼承,這樣可以實現揚長避短的功效。
function SuperType(words){ var colors = ["red","blue","green"]; this.words = words } SuperType.prototype.saySometing = function(){ alert(this.words); } function Subtype(){ SuperType.call(this); } var instance1 = new SubType("hello"); var instance2 = new SubType("what?"); instance1.colors.push("black"); alert(instance1.colors);//"red,blue,green,black" alert(instance2.colors);//"red,blue,green" alert(instance1.saySomething());//"hello" alert(instance2.saySomething());//"what?"
5.原型式繼承
這種繼承方式包含了原型鏈繼承,用一個函式給出一個定了父型別的子型別,這個父型別由函式的引數表示。
function object(){ function F(); F.prototype = o; return new F(); }