js實現繼承的幾種方式

前言:大多OO語言都支持兩種繼承方式:接口繼承和實現繼承,而ECMAScript中沒法實現接口繼承,ECMAScript只支持實現繼承,並且其實現繼承主要是依靠原型鏈來實現。app

1.原型鏈

基本思想:利用原型讓一個引用類型繼承另一個引用類型的屬性和方法。
構造函數,原型,實例之間的關係:每一個構造函數都有一個原型對象,原型對象包含一個指向構造函數的指針,而實例都包含一個指向原型對象的內部指針。函數

原型鏈實現繼承例子:this

function SuperType() {
    this.property = true;
}
SuperType.prototype.getSuperValue = function() {
    return this.property;
}
function subType() {
    this.property = false;
}
//繼承了SuperType
SubType.prototype = new SuperType();
SubType.prototype.getSubValue = function (){
    return this.property;
}

var instance = new SubType();
console.log(instance.getSuperValue());//true

2.借用構造函數

基本思想:在子類型構造函數的內部調用超類構造函數,經過使用call()和apply()方法能夠在新建立的對象上執行構造函數。prototype

例子:指針

function SuperType() {
    this.colors = ["red","blue","green"];
}
function SubType() {
    SuperType.call(this);//繼承了SuperType
}
var instance1 = new SubType();
instance1.colors.push("black");
console.log(instance1.colors);//"red","blue","green","black"

var instance2 = new SubType();
console.log(instance2.colors);//"red","blue","green"

3.組合繼承

基本思想:將原型鏈和借用構造函數的技術組合在一塊,從而發揮二者之長的一種繼承模式。code

例子:對象

function SuperType(name) {
    this.name = name;
    this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function() {
    console.log(this.name);
}
function SubType(name, age) {
    SuperType.call(this,name);//繼承屬性
    this.age = age;
}
//繼承方法
SubType.prototype = new SuperType();
Subtype.prototype.constructor = Subtype;
Subtype.prototype.sayAge = function() {
    console.log(this.age);
}

var instance1 = new SubType("EvanChen",18);
instance1.colors.push("black");
consol.log(instance1.colors);//"red","blue","green","black"
instance1.sayName();//"EvanChen"
instance1.sayAge();//18

var instance2 = new SubType("EvanChen666",20);
console.log(instance2.colors);//"red","blue","green"
instance2.sayName();//"EvanChen666"
instance2.sayAge();//20

4.原型式繼承

基本想法:藉助原型能夠基於已有的對象建立新對象,同時還沒必要須所以建立自定義的類型。繼承

原型式繼承的思想可用如下函數來講明:接口

function object(o) {
    function F(){}
    F.prototype = o;
    return new F();
}

例子:ip

var person = {
    name:"EvanChen",
    friends:["Shelby","Court","Van"];
};

var anotherPerson = object(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = object(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"

ECMAScript5經過新增Object.create()方法規範化了原型式繼承,這個方法接收兩個參數:一個用做新對象原型的對象和一個做爲新對象定義額外屬性的對象。

var person = {
    name:"EvanChen",
    friends:["Shelby","Court","Van"];
};

var anotherPerson = Object.create(person);
anotherPerson.name = "Greg";
anotherPerson.friends.push("Rob");

var yetAnotherPerson = Object.create(person);
yetAnotherPerson.name = "Linda";
yetAnotherPerson.friends.push("Barbie");

console.log(person.friends);//"Shelby","Court","Van","Rob","Barbie"

5.寄生式繼承

基本思想:建立一個僅用於封裝繼承過程的函數,該函數在內部以某種方式來加強對象,最後再像真正是它作了全部工做同樣返回對象。

例子:

function createAnother(original) {
    var clone = object(original);
    clone.sayHi = function () {
        alert("hi");
    };
    return clone;
}

var person = {
    name:"EvanChen",
    friends:["Shelby","Court","Van"];
};
var anotherPerson = createAnother(person);
anotherPerson.sayHi();///"hi"

6.寄生組合式繼承

基本思想:經過借用函數來繼承屬性,經過原型鏈的混成形式來繼承方法
其基本模型以下所示:

function inheritProperty(subType, superType) {
    var prototype = object(superType.prototype);//建立對象
    prototype.constructor = subType;//加強對象
    subType.prototype = prototype;//指定對象
}

例子:

function SuperType(name){
    this.name = name;
    this.colors = ["red","blue","green"];
}
SuperType.prototype.sayName = function (){
    alert(this.name);
};

function SubType(name,age){
    SuperType.call(this,name);
    this.age = age;
}
inheritProperty(SubType,SuperType);
SubType.prototype.sayAge = function() {
    alert(this.age);
}
相關文章
相關標籤/搜索