js繼承的5種方式

一、構造函數綁定

使用call或apply方法,將父對象的構造函數綁定在子對象上。

function Animal(){
    this.species = "動物";
}
		
function Cat(name,color){
    Animal.apply(this,arguments);
    this.name=name;
    this.color=color;
}
		
var cat = new Cat('小白','白');
console.log(cat.species);

二、prototype模式

如果貓的prototype對象,指向一個Animal的實例,那麼所有貓的實例,就能繼承Animal

function Animal(){
    this.species = "動物";
}
		
function Cat(name,color){
    this.name=name;
    this.color=color;
}
		
Cat.prototype = new Animal();
Cat.prototype.constructor = Cat;
var cat = new Cat('小白','白');
console.log(cat.species);

將Cat的prototype的對象指向一個Animal實例,它相當於安全刪除了prototype原來的值,給它賦予了一個新值。

Cat.prototype = new Animal();

任何一個prototype對象都有一個constructor屬性,指向它的構造函數,如果沒有Cat.prototype = new Animal(),Cat.prototype.constructor是指向Cat的,加上這一行,Cat.prototype.constructor指向Animal。這回導致繼承紊亂,必須手動矯正,將Cat的prototype對象的constructor的值改爲Cat

Cat.prototype.constructor = Cat

三、直接繼承prototype

function Animal(){}
Animal.prototype.species = '動物';
		
function Cat(name,color){
    this.name=name;
    this.color=color;
}
		
Cat.prototype = Animal.prototype;
Cat.prototype.constructor = Cat;
console.log('cat',Cat.prototype.constructor);
console.log('animal',Animal.prototype.constructor);

與前一種做法相比,這種的優點是效率比較高(不用創建Animal實例),缺點是Animal.prototype和Cat.prototype指向了同一個對象,任何對Cat.prototype的修改都會影響到Animal.prototype。

Cat.prototype.constructor = Cat;

實際上把Animal的prototype對象的constructor屬性也改掉了

console.log('cat',Cat.prototype.constructor);   //Cat

console.log('animal',Animal.prototype.constructor);  //Cat

四、利用空對象作爲中介

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;
var cat = new Cat('小白','白');
console.log(cat.species);

console.log(Animal.prototype.constructor);   // Animal

F是空對象,所以幾乎不佔內存,修改Cat的prototype對象就不會影響到Animal的prototype對象


可以將上述方法封裝成一個函數

function extend(child,parent){
    var F = function(){};
    F.prototype = parent.prototype;
    child.prototype = new F();
    child.prototype.constructor = Cat;
}

使用方法:

extend(Cat,Animal);
var cat = new Cat('小白','白');
console.log(cat.species);

五、拷貝繼承

首先把Animal上所有不變的屬性都放到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];
        console.log(c[i]);
    }
}

使用方法:

extend(Cat,Animal);
var cat = new Cat('小白','白');
console.log(cat.species);



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章