首先,咱們定義一個父類Animal,接下來用Cat類來實現對這個父類的繼承函數
function Animal (name) { this.name = name || 'Animal'; this.sleep = function(){ console.log(this.name + '正在睡覺!'); } } Animal.prototype.eat = function(food) { console.log(this.name + '正在吃:' + food); };
核心:子類的原型對象等於父類的實例( 子類.prototype=new 父類() )性能
function Cat(){ } Cat.prototype = new Animal(); //若是等於父類prototype,就會改變(指向一樣的地方) 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
優勢:this
缺點:prototype
核心:使用父類的構造函數來得到子類屬性和方法,等因而複製父類的實例屬性給子類(父類.call(this))code
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
優勢:對象
核心:原型式繼承的object方法本質上是對參數對象的一個淺複製。繼承
function Cat(o){ function F(){} F.prototype = o; return new F(); } let cat = object(person); cat.name = "Bob"; anotherPerson.friends.push("Rob");
優勢:父類方法能夠複用
缺點:父類的引用屬性會被全部子類實例共享,子類構建實例時不能向父類傳遞參數
ECMAScript 5 經過新增 Object.create()方法規範化了原型式繼承。這個方法接收兩個參數:一 個用做新對象原型的對象和(可選的)一個爲新對象定義額外屬性的對象。在傳入一個參數的狀況下, Object.create()與 object()方法的行爲相同。 因此上文中代碼能夠轉變爲
let cat = Cat(Animal); => let cat = Object.create(Animal);ip
核心:子類.prototype.屬性=new 父類().屬性內存
function Cat(name){ var animal = new Animal(); for(var p in animal){ Cat.prototype[p] = animal[p]; } Cat.prototype.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
優勢:原型鏈
缺點:
核心:經過調用父類構造,繼承父類的屬性並保留傳參的優勢,而後經過將父類實例做爲子類原型,實現函數複用(父類.call(this),子類.prototype=new 父類())
function Cat(name){ Animal.call(this); this.name = name || 'Tom'; } Cat.prototype = new Animal(); // 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
優勢:
缺點:
經過寄生方式,砍掉父類的實例屬性,這樣,在調用兩次父類的構造的時候,就不會初始化兩次實例方法/屬性,避免的組合繼承的缺點(父類.call(this).var Super=function(){},Super.prototype=父類.prototype,子類.prototype=new Super)
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
優勢:
缺點:
class 子類 extends 父類{constructor(){super()}}
class Cat extends Animal { constructor(name,food){ //調用父類的constructor(name) super(name); this.food = food } eat(food){ //調用父類的方法 super.eat(food); } } // 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