一、 構造函數綁定
- 使用call或apply方法,将父對象的構造函數綁定在子對象上
function Animal(){
this.species = "動物";
}
function Cat(name,color){
Animal.apply(this, arguments);
this.name = name;
this.color = color;
}
var cat1 = new Cat("大毛","黃色");
console.log(cat1.species);
console.log(Cat.prototype);
console.log(Cat.constructor);
console.log(cat1.constructor);
二、 prototype模式
- 将子對象(Cat)的prototype對象,指向父對象(Animal)的執行個體
- 任何一個prototype對象都有一個constructor屬性,指向它的構造函數(此例為Cat),但是因為第一行把Cat的prototype原型對象指向了Animal,是以需要手動改回Cat,否則會導緻繼承鍊的紊亂,這是很重要的一點,程式設計時務必要遵守
- 即替換了如果替換了prototype原型對象,下一步必然是為新的prototype對象加上constructor屬性,并将這個屬性指回原來的構造函數
function Animal(){
this.species = "動物";
}
function Cat(name,color){
this.name = name;
this.color = color;
}
Cat.prototype = new Animal(); //完全删除了prototype 對象原先的值,然後賦予一個新值。
console.log(Cat.prototype.constructor) //Animal
Cat.prototype.constructor = Cat; //防止繼承鍊紊亂
console.log(Cat.prototype.constructor); //Cat
var cat1 = new Cat("大毛","黃色");
console.log(cat1.species); //動物
console.log(cat1.constructor); //Cat
三、 直接繼承prototype
- 第三種方法是對第二種方法的改進。由于Animal對象中,不變的屬性都可以直接寫入Animal.prototype。是以,我們也可以讓Cat()跳過 Animal(),直接繼承Animal.prototype。
- 與前一種方法相比,這樣做的優點是效率比較高(不用執行和建立Animal的執行個體了),比較省記憶體。缺點是 Cat.prototype和Animal.prototype現在指向了同一個對象,那麼任何對Cat.prototype的修改,Animal.prototype也跟着修改。
function Animal(){ }
Animal.prototype.species = "動物";
function Cat(name,color){
this.name = name;
this.color = color;
}
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
var cat1 = new Cat("大毛","黃色");
console.log(cat1.species); // 動物
Cat.prototype.weight = ; //給Cat的原型添加屬性
console.log(Cat.prototype) //多了weight屬性
console.log(Animal.prototype) //多了weight屬性
四、 利用空對象作為中介
- 跟直接繼承差不多,隻是多了個空對象作為中介,空對象幾乎不占記憶體
function Animal(){}
Animal.prototype.species = "動物";
function Cat(name,color){
this.name = name;
this.color = color;
}
var F = function(){};
F.prototype = Animal.prototype;
Cat.prototype = new F();
Cat.prototype.constructor = Cat;
Cat.prototype.weight = ;
var cat = new Cat('星星','黑白');
console.log(cat.species);
console.log(Animal.prototype.constructor);
console.log(Cat.prototype.constructor);
//繼承方法的封
function extend(Child, Parent) {
var F = function(){};
F.prototype = Parent.prototype;
Child.prototype = new F();
Child.prototype.constructor = Child;
Child.uber = Parent.prototype;
//意思是為子對象設一個uber屬性,這個屬性直接指向父對象的prototype屬性。這等于在子對象上打開一條通道,可以直接調用父對象的方法。這一行放在這裡,隻是為了實作繼承的完備性,純屬備用性質。
}
五、 拷貝繼承
- 把父對象的所有屬性和方法,拷貝進子對象
- -
function Animal(){}
Animal.prototype.species = "動物";
function Cat(name,color){
this.name = name;
this.color = color;
}
//封裝拷貝繼承方法
function extend(Child, Parent) {
var p = Parent.prototype;
var c = Child.prototype;
for (var i in p) {
c[i] = p[i];
}
c.uber = p;
}
extend(Cat, Animal);
var cat = new Cat("大毛","黃色");
console.log(cat.species);
Cat.prototype.weight =
console.log(Cat.prototype)
console.log(Animal.prototype)