繼承的方法有很多挎狸,有的存在明顯缺點扣汪,我選擇了以下三種方法來記憶并使用。
1.使用prototype锨匆,并利用空對象作為中介
(摘自avascript面向對象編程(二):構造函數(shù)的繼承)
由于"直接繼承prototype"存在缺點崭别,所以就有第四種方法,利用一個空對象作為中介恐锣。
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
F是空對象茅主,所以幾乎不占內(nèi)存。這時土榴,修改Cat的prototype對象诀姚,就不會影響到Animal的prototype對象。
alert(Animal.prototype.constructor); // Animal
我們將上面的方法鞭衩,封裝成一個函數(shù)学搜,便于使用。
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
}
使用的時候论衍,方法如下
extend(Cat,Animal);
var cat1 = new Cat("大毛","黃色");
alert(cat1.species); // 動物
這個extend函數(shù)瑞佩,就是YUI庫如何實現(xiàn)繼承的方法。
另外坯台,說明一點炬丸,函數(shù)體最后一行
Child.uber = Parent.prototype;
意思是為子對象設一個uber屬性,這個屬性直接指向父對象的prototype屬性蜒蕾。(uber是一個德語詞稠炬,意思是"向上"、"上一層"咪啡。)這等于在子對象上打開一條通道首启,可以直接調(diào)用父對象的方法。這一行放在這里撤摸,只是為了實現(xiàn)繼承的完備性毅桃,純屬備用性質(zhì)褒纲。
2.拷貝繼承
(摘自avascript面向對象編程(二):構造函數(shù)的繼承)
上面是采用prototype對象,實現(xiàn)繼承钥飞。我們也可以換一種思路莺掠,純粹采用"拷貝"方法實現(xiàn)繼承。簡單說读宙,如果把父對象的所有屬性和方法彻秆,拷貝進子對象,不也能夠實現(xiàn)繼承嗎结闸?這樣我們就有了第五種方法唇兑。
首先,還是把Animal的所有不變屬性膀估,都放到它的prototype對象上幔亥。
function Animal(){}
Animal.prototype.species = "動物";
然后,再寫一個函數(shù)察纯,實現(xiàn)屬性拷貝的目的帕棉。
function extend2(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
這個函數(shù)的作用,就是將父對象的prototype對象中的屬性饼记,一一拷貝給Child對象的prototype對象香伴。
使用的時候,這樣寫:
extend2(Cat, Animal);
var cat1 = new Cat("大毛","黃色");
alert(cat1.species); // 動物
3.Object.create
ES5中定義了該方法具则。使用它即纲,可以很簡單地完成繼承。
實例1
var Parent = {
getName: function() {
return this.name;
}
}
var child = Object.create(Parent, {
name: { value: "Benjamin"},
url : { value: "http://www.zuojj.com"}
});
//Outputs: Object {name: "Benjamin", url: "http://www.zuojj.com", getName: function}
console.log(child);
//Outputs: Benjamin
console.log(child.getName());
實例2
var Parent = {
getName: function() {
return this.name;
},
getSex: function() {
return this.sex;
}
}
var Child = Object.create(Parent, {
name: { value: "Benjamin"},
url : { value: "http://www.zuojj.com"}
});
var SubChild = Object.create(Child, {
name: {value: "zuojj"},
sex : {value: "male"}
})
//Outputs: http://wwww.zuojj.com
console.log(SubChild.url);
//Outputs: zuojj
console.log(SubChild.getName());
//Outputs: undefined
console.log(Child.sex);
//Outputs: Benjamin
console.log(Child.getName());