每日靈魂一問-繼承的6種方法(上)

一.原型鏈繼承(prototype)函數

就是把要繼承的方法寫在原型鏈上性能

function Parent() {
    this.name = 'parent1';
    this.play = [1, 2, 3]
  }
  function Child() {
    this.type = 'child2';
  }
  Child.prototype = new Parent();

缺點:實例化的對象共用一個內存地址this

二.構造函數繼承(call)prototype

function Parent(){
    this.name = 'parent1';
}

Parent.prototype.getName = function () {
    return this.name;
}

function Child(){
    Parent.call(this);
    this.type = 'child'
}

let child = new Child();
console.log(child);  // 沒問題
console.log(child.getName());  // 會報錯

可是隻能繼承父類的實例屬性和方法,不能繼承原型屬性或者方法code

三.組合繼承(手動掛上構造器,指向本身的構造函數)對象

function Parent3 () {
    this.name = 'parent3';
    this.play = [1, 2, 3];
}

Parent3.prototype.getName = function () {
    return this.name;
}

function Child3() {
// 第二次調用 Parent3()
    Parent3.call(this);
    this.type = 'child3';
}

// 手動掛上構造器,指向本身的構造函數
// 第一次調用 Parent3()
Child3.prototype = new Parent3();
Child3.prototype.constructor = Child3;

var s3 = new Child3();
var s4 = new Child3();
s3.play.push(4);
console.log(s3.play, s4.play);  // 不互相影響
console.log(s3.getName()); // 正常輸出'parent3'
console.log(s4.getName()); // 正常輸出'parent3'

缺點:形成了多構造一次的性能開銷繼承