在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 原型鏈實(shí)現(xiàn)繼承的疑問?

原型鏈實(shí)現(xiàn)繼承的疑問?

以下是我的嘗試過程

First

function Parent() {
    this.count = 1;
    this.addCount = function() {
        console.log(++this.count);
    };
    this.items = [];
    this.addItem = function(item) {
        this.items.push(item);
        console.log(this.items);
    };
}

function Child() {
}

Child.prototype = new Parent();

var child1 = new Child();
var child2 = new Child();

child1.addCount(); // 2
child2.addCount(); // 2
child1.addItem('child1'); // child1
child2.addItem('child2'); // child1, child2

console.log(child1);
/*
    count: 2
    __proto__: Parent
        count: 1
        items: ['child1', 'child2']
        addCount: function
        addItem: function
    
*/

Result

發(fā)現(xiàn)有個(gè)問題,引用屬性共享了

Try agian

// 忽略未修改的代碼
function Child() {
    Parent.call(this); // 顯示調(diào)用父類的構(gòu)造函數(shù)
}
console.log(child1);
/*
    count: 2
    items: ['child1']
    addCount: function
    addItem: function
    __proto__: Parent
        count: 1
        items: []
        addCount: function
        addItem: function
    
*/

Result

重復(fù)定義了addCount和addItem方法

Try again

// 忽略未修改的代碼
function Parent() {
    this.count = 1;
    this.items = [];
}

Parent.prototype.addCount = function() {
    console.log(++this.count);
};

Parent.prototype.addItem = function(item) {
    this.items.push(item);
    console.log(this.items);
};
console.log(child1);
/*
    count: 2
    items: ['child1']
    __proto__: Parent
        count: 1
        items: []
        addCount: function
        addItem: function
    
*/

Result

從結(jié)果上看簡(jiǎn)單實(shí)現(xiàn)了繼承,但是有幾個(gè)疑問:

  1. Object.create or new
  2. 如何實(shí)現(xiàn)非引用類型屬性的共享
  3. 顯式調(diào)用父類的構(gòu)造函數(shù)感覺很繁瑣,看能不能去掉
  4. 多重繼承?

大家是怎么使用原型鏈實(shí)現(xiàn)繼承的呢?

--------------- 2018/1/18 13:45 ------------------------

看了@Maxiye提供的文章,也許可以使用簡(jiǎn)單的混合實(shí)現(xiàn),類似于php的trait,針對(duì)某些情況可能比較適用

// 去掉原型鏈關(guān)聯(lián)
// Child.prototype = new Parent();

function Child() {
    Parent.call(this);
}
回答
編輯回答
蟲児飛

推薦看看這篇文章:徹底弄懂JS繼承

2018年2月17日 00:08
編輯回答
半心人

解釋一下"First" 的輸出結(jié)果。

function Parent() {
    this.count = 1;
    this.addCount = function() {
        console.log(++this.count);
    };
    this.items = [];
    this.addItem = function(item) {
        this.items.push(item);
        console.log(this.items);
    };
}

function Child() {
}

Child.prototype = new Parent();

var child1 = new Child();
var child2 = new Child();

child1.addCount(); // 2
child2.addCount(); // 2
child1.addItem('child1'); // child1
child2.addItem('child2'); // child1, child2

你這個(gè)代碼的問題不是不能繼承。其實(shí)child1 和child2 都繼承了Parent 的property.

var child1 = new Child(); // child1 : {} initial 了一個(gè)空的child1, 它的__.proto__ 是 new Parent()
var child2 = new Child(); // child2 : {} initial 了一個(gè)空的child2, 它的__.proto__ 是 new Parent()
child1.addCount(); // child1: {count: 2} 調(diào)用child1的addCount(), 沒有這個(gè)函數(shù),找原型鏈, 找到, 這時(shí)候 addCount() 中的this 指向的是child1, 所以++this.count 相當(dāng)于:this.count = this.count + 1, 相當(dāng)于一個(gè)賦值: child1.count = 2;
child2.addCount(); // child2: {count: 2} 原理同上
child1.addItem('child1'); // child1: {count: 2} 調(diào)用 child1中的addItem(),沒有這個(gè)函數(shù),找原型鏈,找到。 這時(shí)候addItem()中的this 指向的也是child1, 但是child1 沒有items這個(gè)property,不能push,所以只能找原型鏈中的items,找到。所以這個(gè)push ,就是對(duì)原型鏈里面的items.push(child1).
child2.addItem('child2'); // child2: {count: 2} 調(diào)用 child2中的addItem(),沒有這個(gè)函數(shù),找原型鏈,找到。 這時(shí)候addItem()中的this 指向的也是child2, 但是child2 沒有items這個(gè)property,所以只能找原型鏈,找到。所以這個(gè)push ,就是對(duì)原型鏈里面的items.push(child2), 所以原型鏈里面的items 就是[child1, child2].

加一行代碼就能實(shí)現(xiàn)你想要的繼承:

function Parent() {
    this.count = 1;
    this.addCount = function() {
        console.log(++this.count);
    };
    this.items = [];
    this.addItem = function(item) { 
        this.items=[];//加了這一行,每一個(gè)調(diào)用addItem的child,都給它initial 一個(gè)items 
        this.items.push(item);
        console.log(this.items);
    };
}

function Child() {
}

Child.prototype = new Parent();

var child1 = new Child();
var child2 = new Child();

child1.addCount(); // 2
child2.addCount(); // 2
child1.addItem('child1'); // child1
child2.addItem('child2'); // child2
2017年10月10日 15:47