Javascript函数'对象之间共享原型??

时间:2014-08-13 01:51:47

标签: javascript design-patterns prototype

我找到的所有资源,它说如果我们使用Javascript原型模式,那就是'原型在该特定类型的所有对象之间共享。 这意味着以下内容;

function TestObj(){
}

TestObj.prototype = {
    cVar: 15,
    increase: function(){
        this.cVar++;
    }
};

var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar); // 16
console.log(b.cVar); // 15 ??

现在我的问题是,b.cVar不应该是16吗?那为什么呢?如果它是15则意味着具有protype的TestObj不在对象之间共享。

你知道吗?

4 个答案:

答案 0 :(得分:6)

是的,对象的原型在对象的实例之间共享,但this.cVar++看起来有点误导。

我认为如果你重写

会更容易解释
this.cVar++;

作为

this.cVar = this.cVar + 1;

重要的是this指的是对象实例,而不是原型。因此,在this.cVar + 1中,它将检查对象实例以查看它是否具有cVar属性。第一次调用increase时,它不会。所以JavaScript会查找原型链,直到找到它为止。所以它找到了15。但是,当它将实际赋值返回到this.cVar时,它会在对象实例本身上设置属性,而不是原型(对各种类型的影子)。

所以在你的例子中,

console.log(a.cVar); // returns property from `a` itself
console.log(b.cVar); // returns property from the prototype

我们可以使用hasOwnProperty

来证明这一点
console.log( a.hasOwnProperty( "cVar" ) ); // true
console.log( b.hasOwnProperty( "cVar" ) ); // false

答案 1 :(得分:3)

事实上,对象确实与您相互分享原型,因为您的研究已经让您相信。然而,正如go-oleg所提到的那样,有一个原型链的概念。原型链有一些您必须了解的行为。

当您尝试访问对象上的属性时,它以递归方式从对象开始查找链并查找属性,然后返回值(这是读取/获取时发生的情况动作)。

当您尝试在对象上的属性上设置值时,它并不需要递归链以查找链中的属性。相反,如果它没有在对象上找到一个,它只会添加属性以及您在对象本身上设置的值。这有效地隐藏了原型链中较高的属性(这是写/置动作的情况)。

如果您将值放在一个对象中然后尝试设置该值,它会在读取尝试时递归到对象引用,并且由于您有一个指向该对象的引用指针,您将在该对象上设置该值直接哪个会产生你期望的结果:

function TestObj(){
}

TestObj.prototype = {
    cVar: 15,
    obj: { val: 5 },
    increase: function(){
        this.cVar++;
    },
    objInc: function() { 
        this.obj.val++;
    }
};

var a = new TestObj();
var b = new TestObj();
a.increase();
console.log(a.cVar);
console.log(b.cVar);

b.objInc();
console.log(a.obj.val);
console.log(b.obj.val);

//output
//16
//15
//6
//6

希望这种区别可以消除混乱。

答案 2 :(得分:0)

要清楚," a"是一个对象," b"是另一个独立的对象。 然后,您只能在" a"而不是" b"上调用增加功能。因此,除非我离开摇杆,否则 b.cVar = 15是有意义的,因为它从未递增过。

答案 3 :(得分:0)

您对术语感到困惑,而TestObject aTestObject唯一被称为increase()的{​​{1}}。因此,a = 16b = 16是有意义的,因为您从不致电b.increase()

  

......函数'原型在该特定类型的所有对象之间共享。

这并不意味着每次TestObject调用increase(),然后每隔一个TestObject,其本身也会增加cVar。您对类似于设置EventListenerEventDispatcher系统的方式的想法。该函数的原型在该特定类型的所有对象之间共享意味着每个TestObject实例都具有您定义的原型。