为什么共享继承的数组而不是普通的变量?

时间:2012-11-22 09:14:59

标签: javascript arrays inheritance member

foo1foo2继承自人。 为什么foo1.afoo2.a相同?

    var foo1, foo2;

    var person = function(a) {
        this.a = []
        this.b = 1;
        console.log('construct 1');
    }

    var kevin = function(a, b) {
        console.log('construct 2');
    }

    kevin.prototype = new person();

    foo1 = new kevin();
    foo2 = new kevin();

    foo1.a[3] = true;
    foo1.a[1] = true;
    foo2.a[1] = false;
    foo1.b = 2;
    foo2.b = 3;
    console.log(foo1.a);
    console.log(foo1.b);
    console.log(foo2.a);
    console.log(foo2.b);

为什么foo*.a会分享? 为什么foo*.b没有共享?

2 个答案:

答案 0 :(得分:0)

尝试:

function kevin( a, b ){
    Person.call( this, a );
    this.b = b;
    //do extra kevin stuff here...

}

您需要调用超级构造函数。也许this article也会给你一些如何实现继承的想法。

答案 1 :(得分:0)

对象(包括数组)存储为引用。基元(包括数字)存储为值。

new person()创建一个新人,并引用一个空数组。您将此对象(不是类,对象!)指定为kevin的原型。

foo1.a不存在,因此a查找原型链,我们在其中找到之前找到的空数组。当我们修改这个数组的内容时,我们仍然有未定义的foo1.a。您已更改了数组内容,但未更改引用的值(不在原型上,当然也不在foo1上)。

foo2.a也不存在,因此a再次在原型上查找 - 从之前找到相同的数组(现在包含从我们通过{{访问它时)的一些更改1}})。

相反,foo1将在foo1.b = ...上定义新值。 foo1的下一个查找不会沿着原型链向上移动。除此之外,数字不能被更改,只是被覆盖,因此您无法进入内容更改和身份不同的情况,例如对象。

所以 - 你在这里有两种不同的现象,它们都是你所询问的行为的常见嫌疑人。具体来说,原型继承是罪魁祸首,但这只发生在JavaScript和类似语言中(其中没有太多)。在大多数其他情况下,类似的问题是由参考/值区分引起的。