JS中對象繼承方式


JS對象繼承方式

摘自《JavaScript的對象繼承方式,有幾種寫法》,作者:peakedness
鏈接:https://my.oschina.net/u/3970421/blog/2872629

方式一:對象冒充

原理:構造函數使用this關鍵字給所有屬性和方法賦值(即采用類聲明的構造函數方式)。因為構造函數只是一個函數,所以可使Parent構造函數稱為Children的方法,然后調用它。Children會收到Parent的構造函數中定義的屬性和方法。


//父類構造函數
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的構造函數,沒有給它傳遞參數。這是原型鏈中的標准做法,要確保構造函數沒有任何參數。

方式三:使用call或apply方法

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

//父類構造函數
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中創建類,最好使用構造函數定義屬性,使用原型鏈定義方法。

//父類構造函數
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方法會使用指定的原型對象及其屬性去創建一個新的對象

//父類構造函數
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指向創建此對象的函數的引用。

方式六: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);


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM