1. 程式人生 > >JavaScript常用的幾種繼承方式

JavaScript常用的幾種繼承方式

功能 col 中轉 var 函數 實現 所有 目標 emp

JavaScript是面向對象的弱類型語言,繼承是其重要的特性之一,這裏總結下常用的四種繼承方法。

先定義一個父級構造函數,並在其原型上添加一個speak方法

//定義父級構造函數
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.intro = function() {
        console.log(this.name + ‘ is ‘ + this.age + ‘ years old‘);
    }
}
//父級原型添加新方法
Person.prototype.speak = function
(language) { console.log(this.name + ‘ can speak ‘ + language); }

以下四種繼承方式均在此父級構造函數基礎上實現。

1、傳統形式,通過原型鏈繼承

將父級構造函數的實例作為子級構造函數的原型

//定義子級構造函數
function Man() {

}
//將父級實例作為子級原型
Man.prototype = new Person(‘Jack‘, 18);
//子級原型添加name屬性會覆蓋原型name屬性
Man.prototype.name = ‘Toms‘;
//創建子級實例對象
var man = new
Man(); //調用父級構造函數內的方法 man.intro(); // Toms is 18 years old //調用父級原型自定義的speak方法 man.speak(‘Chinese‘); // Toms can speak Chinese

缺點:繼承父級所有屬性和方法,沒有選擇性

2、通過父級構造函數,即子級構造函數內調用父級構造函數

其實就是借用別人的方法,實現自己的功能

function Man() {
    Person.call(this);
    this.name = ‘Jack‘;
    this.age = 19
}
var man = new
Man();
// 借用Person的intro方法 man.intro();
// Jack is 19 years old

缺點:不能繼承父級構造函數原型,每次創建實例要多運行一個構造函數

3、通過原型共享實現繼承

即子級原型等於父級原型

function Man(name) {
    this.name = name;
}
//構造函數原型共享
Man.prototype = Person.prototype;
var man = new Man(‘Jack‘);
//子級實例可調用共享的原型上的方法speak
man.speak(‘Chinese‘); // Jack can speak Chinese

缺點:共享原型,一個修改原型屬性和方法,另一個會同步

4、堪稱完美的聖杯模式

通過在一個立即執行函數中定義一個臨時構造函數,來中轉源構造函數到目標構造函數的原型鏈,這樣修改目標構造函數的原型不會直接影響到源構造函數原型,

同時執行完畢立即銷毀,減少內存開銷。

var inherit = (function () {
    var Temp = function () {}; // 定義臨時構造函數用於原型鏈的中轉
    return function (Target, Origin) {
        Temp.prototype = Origin.prototype; // Temp繼承Origin原型
        Target.prototype = new Temp(); // Target繼承Temp對象原型
        Target.prototype.constructor = Target; // 改寫Target原型上的構造器指向
        Target.prototype.ancestor = Origin.prototype; // 標記Target真正繼承的原型
    }
}());

JavaScript常用的幾種繼承方式