JS中對象繼承方式

JS對象繼承方式

摘自《JavaScript的對象繼承方式,有幾種寫法》,做者:peakedness
連接:http://www.javashuo.com/article/p-zmgddvlv-hz.html數組

方式一:對象冒充

原理:構造函數使用this關鍵字給全部屬性和方法賦值(即採用類聲明的構造函數方式)。由於構造函數只是一個函數,因此可以使Parent構造函數稱爲Children的方法,而後調用它。Children會收到Parent的構造函數中定義的屬性和方法。
***app

//父類構造函數
var Parent = function(name){
    this.name = name;
    this.sayHi = function(){
        console.log("Hi" + this.name + ".");
    }
}

var Children = function(name){
    
    this.method = Parent;
    this.method(name);  //實現繼承
    delete this.method;

    this.getName = function(){
        console.log(this.name);
    }
}

var P = new Parent("john");
var C = new Children("joe");

P.sayHi();      //Hi john
C.sayHi();      //Hi joe
C.getName();    //joe

方式二:原型鏈繼承

原理:JS是一門基於原型的語言。在JS中prototype對象的任何屬性和方法都被傳遞給那個類的全部實例。函數

//父類構造函數
var Parent = function(name){
    this.name = name;
    this.sayHi = function(){
        console.log("Hi" + this.name + ".");
    }
}
//子類構造函數
var Children = function(){};

Children.prototype = new Parent();

var P = new Parent();
var C = new Children();

P.sayHi();
C.sayHi();

注意:
調用Parent的構造函數,沒有給它傳遞參數。這是原型鏈中的標準作法,要確保構造函數沒有任何參數。this

方式三:使用call或apply方法

原理:經過改變this指向實現繼承。apply第二個參數必須是數組,call依次傳入。.net

//父類構造函數
var Parent = function(name){
    this.name = name;
    this.sayHi = function(){
        console.log("Hi" + this.name + ".");
    }
};
//子類構造函數
var Children = function(name){
    Parent.call(this,name);
    this.getName = function(){
        console.log(this.name);
    }
};
var C = new Children("Joe");
C.sayHi();  //Hi john
C.getName();    //Joe

方式四:混合使用(推薦)

使用原型鏈就沒法使用帶參數的構造函數了
所以,在JS中建立類,最好使用構造函數定義屬性,使用原型鏈定義方法。prototype

//父類構造函數
var Parent = function(name){
    this.name = name;
}
Parent.prototype.sayHi = function(){
    console.log("Hi ! " + this.name + "!!!");
}
var P = new Parent("John");
P.sayHi();  //Hi John !!!

方式五:使用Object.create方法

Object.create方法會使用指定的原型對象及其屬性去建立一個新的對象code

//父類構造函數
var Parent = function(name){
    this.name = name;
}
Parent.prototype.sayHi = function(){
    console.log("Hi " + this.name + ".");
}
//子類構造函數
var Children = function(name,age){
    this.age = age;
    Parent.call(this,name);     //屬性不在prototype上
};

Children.prototype = Object.create(Parent.prototype);
Children.prototype.constructor = Children;
Children.prototype.getAge = function(){
    console.log(this.age);
};

var P = new Parent("John");
var C = new Children("Joe",30);

P.sayHi();  //Hi John
C.sayHi();  //Hi Joe
C.getAge(); //30

注意:
當執行Children.prototype = Object.create(Parent.prototype)這個語句後,Children的constructor就被變爲Parent,所以須要將Children.protype.constructor從新指定爲Children自己。對象

constructor指向建立此對象的函數的引用。blog

方式六:extends關鍵字實現繼承

class Paren{
    constructor(name,age){
        this.name = name;
        this.age = age;
    }
}
class Children extends Parent{
    constructor(name,age,job){
        super(name,age);    //super必須在前,不然代碼報錯
        this.job = job;
    }
}

注意:
子類的constructor方法沒有調用super以前,就使用this關鍵字會報錯。緣由是:子類Children的構造函數之中的super(),表明調用父類Parent的構造函數。繼承

super雖然表明了父類Parent的構造函數,可是返回的是子類Children的實例,即super內部的this指的是Children,所以super()在這裏至關於Parent.prototype.constructor.call(this);

相關文章
相關標籤/搜索