2025-04-30

原型鏈繼承

引用類型值的原型屬性會被所有實例共享
在創建子類型的實例時,不能向超類型的構造函數中傳遞參數。

function SuperType(){
this.colors = ["red", "blue", "green"];
}
function SubType(){
}
//繼承瞭 SuperType
SubType.prototype = new SuperType();
var instance1 = new SubType();
instance1.colors.push("black");
alert(instance1.colors); //"red,blue,green,black"
var instance2 = new SubType();
alert(instance2.colors); //"red,blue,green,black"

構造函數繼承:解決瞭原型鏈中的兩個問題,但又出現瞭新的問題。

超類型的原型中定義的方法,對子類型而言也是不可見的,方法都在構造函數中定義,因此函數復用就無從談起瞭

組合繼承:解決瞭原型鏈和構造函數繼承的問題,但出現新的問題:

在第一次調用 SuperType 構造函數時,SubType.prototype 會得到兩個屬性: name 和 colors;它們都是 SuperType 的實例屬性,隻不過現在位於 SubType 的原型中。

當調用 SubType 構造函數時,又會調用一次 SuperType 構造函數,這一次又在新對象上創建瞭實例屬性 name 和 colors。於是,這兩個屬性就屏蔽瞭原型中的兩個同名屬性。出現瞭多餘的屬性

function SuperType(name){
this.name = name;
this.colors = ["red", "blue", "green"];
}
SuperType.prototype.sayName = function(){
alert(this.name);
};
function SubType(name, age){
SuperType.call(this, name); //第二次調用 SuperType()
this.age = age;
}
SubType.prototype = new SuperType(); //第一次調用 SuperType()
SubType.prototype.constructor = SubType;
SubType.prototype.sayAge = function(){
alert(this.age);
};

共享原型:

子類原型和父類原型共享,指向同一個原型對象,修改子類原型會影響父類原型。

function SuperType() {
   }
    SuperType.prototype.name = "Tom";
	function SubType() {
	}
	function inherit(Target,Origin){
		Target.prototype = Origin.prototype;
	}
	inherit(SubType,SuperType);
	SubType.prototype.name = "Jack";
	var test1 = new SubType();
	var test2 = new SuperType();
	console.log(test1.name);//Jack 
	console.log(test2.name);//Jack 

進行改進:聖杯模式

function SuperType() {
   }
    SuperType.prototype.name = "Tom";
	function SubType() {
	}
	function inherit(Target,Origin){
		function F(){};
		F.prototype = Origin.prototype
		Target.prototype = new F();
		Target.prototype.constructor = Target;
		Target.prototype.uber = Origin.prototype;
	}
	inherit(SubType,SuperType);
	SubType.prototype.name = "Jack";
	var test1 = new SubType();
	var test2 = new SuperType();
	console.log(test1.name);//Jack 
	console.log(test2.name);//Tom 

Yahoo寫法:利用瞭閉包。

var inherit = (function(Target,Origin){
	var F = function(){};
	return function(){
		F.prototype = Origin.prototype
		Target.prototype = new F();
		Target.prototype.constructor = Target;
		Target.prototype.uber = Origin.prototype;	
		}
}())

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *