javascript實作繼承的方式:1、原型鏈繼承;將父類別的實例當作子類別的原型。 2、建構繼承;使用父類別的建構子來增強子類別實例。 3、實例繼承;為父類別實例新增特性,以子類別實例傳回。 4、拷貝繼承。 5、組合繼承。 6.寄生組合繼承。
本教學操作環境:windows7系統、javascript1.8.5版、Dell G3電腦。
JS作為物件導向的弱型別語言,繼承也是其非常強大的特性之一。那麼如何在JS中實現繼承呢?讓我們拭目以待。
既然要實作繼承,那麼首先我們得有一個父類,程式碼如下:
// 定义一个动物类 function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } } // 原型方法 Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };
核心: 將父類別的實例作為子類別的原型
function Cat(){ } Cat.prototype = new Animal(); Cat.prototype.name = 'cat'; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.eat('fish')); console.log(cat.sleep()); console.log(cat instanceof Animal); //true console.log(cat instanceof Cat); //true
特點:
非常純粹的繼承關係,實例是子類別的實例,也是父類別的實例
父類別新增原型方法/原型屬性,子類別都能存取到
#簡單,易於實作
缺點:
#要想為子類別新增屬性與方法,可以在Cat建構函數中,為Cat實例增加實例屬性。如果要新增原型屬性和方法,則必須放在new Animal()這樣的語句之後執行。
無法實作多重繼承
來自原型物件的所有屬性被所有實例共用
建立子類別實例時,無法向父類別建構子傳參
核心:使用父類別的建構子來增強子類別實例,等於複製父類別的實例屬性給子類別(沒用到原型)
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
特點:
#核心:為父類別實例新增特性,作為子類別實例傳回
function Cat(name){ var instance = new Animal(); instance.name = name || 'Tom'; return instance; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // false
new 子類別()還是
子類別(),傳回的物件具有相同的效果
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } // 如下实现修改了原型对象,会导致单个实例修改name,会影响所有实例的name值 // Cat.prototype.name = name || 'Tom'; 错误的语句,下一句为正确的实现 this.name = name || 'Tom'; } // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // false console.log(cat instanceof Cat); // true
核心:透過呼叫父類別構造,繼承父類別的屬性並保留傳參的優點,然後透過將父類別實例作為子類別原型,實現函數重複使用
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); // 组合继承也是需要修复构造函数指向的。 Cat.prototype.constructor = Cat; // Test Code var cat = new Cat(); console.log(cat.name); console.log(cat.sleep()); console.log(cat instanceof Animal); // true console.log(cat instanceof Cat); // true
透過寄生方式,砍掉父類別的實例屬性,這樣,在呼叫兩次父類別的建構的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點function Cat(name){
Animal.call(this);
this.name = name || 'Tom';
}
(function(){
// 创建一个没有实例方法的类
var Super = function(){};
Super.prototype = Animal.prototype;
//将实例作为子类的原型
Cat.prototype = new Super();
})();
// Test Code
var cat = new Cat();
console.log(cat.name);
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true
Cat.prototype.constructor = Cat; // 需要修复下构造函数
function Animal (name) { // 属性 this.name = name || 'Animal'; // 实例方法 this.sleep = function(){ console.log(this.name + '正在睡觉!'); } //实例引用属性 this.features = []; } function Cat(name){ } Cat.prototype = new Animal(); var tom = new Cat('Tom'); var kissy = new Cat('Kissy'); console.log(tom.name); // "Animal" console.log(kissy.name); // "Animal" console.log(tom.features); // [] console.log(kissy.features); // [] tom.name = 'Tom-New Name'; tom.features.push('eat'); //针对父类实例值类型成员的更改,不影响 console.log(tom.name); // "Tom-New Name" console.log(kissy.name); // "Animal" //针对父类实例引用类型成员的更改,会通过影响其他子类实例 console.log(tom.features); // ['eat'] console.log(kissy.features); // ['eat']
【相關推薦:javascript學習教學】
以上是javascript實作繼承的方式有哪些的詳細內容。更多資訊請關注PHP中文網其他相關文章!