JavaScript常用的幾種繼承方式
阿新 • • 發佈:2019-01-12
功能 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 = newMan(); //調用父級構造函數內的方法 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 = newMan();
// 借用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常用的幾種繼承方式