任何人都可以帮助我理解为什么“counter”属性似乎会在每个新实例上重置?我希望它像“letters”属性一样工作,它在所有实例化对象之间共享。
我遇到了一些示例代码,同时为什么原型属性不应该以这种方式使用,除非它们是静态的。
示例代码:
var Dog = function() {
this.initialize.apply(this, arguments);
};
Dog.prototype = {
counter : 2,
letters : [ 'a', 'b', 'c' ],
initialize : function(dogName) {
this.dogName = dogName;
},
add : function(amount) {
this.counter += amount;
},
arr : function(char) {
this.letters.push(char);
}
};
var fido = new Dog("fido");
fido.add(1);
fido.arr('d');
console.log(fido.counter); // 3, as expected
console.log(fido.letters.toString()); // ABCD, as expected
var maxx = new Dog("maxx");
maxx.add(1);
maxx.arr('e');
console.log(maxx.counter); // 3, Unexpected, Why isn't this 4?
console.log(maxx.letters.toString()); // ABCDE, as expected
答案 0 :(得分:3)
这是由于行
this.counter += amount;
会发生什么? this.counter
在实例上找不到属性计数器,因此它从原型中获取它,但是当涉及到设置时,它会在实例上设置它
var fido = new Dog("fido");
console.log(fido.hasOwnProperty('counter')); // false
fido.add(1);
console.log(fido.hasOwnProperty('counter')); // true
记住它是
的简写this.counter = this.counter + amount;
/* ↑ ↑
instance |
prototype */
对于字母,由于push
正在原型中的 Object 上发生,因此正在按预期工作 - 您没有设置新的实例变量。如果您正在设置实例变量,它仍然可以工作,因为 Objects 通过引用分配给变量,即
var a = {}, b = a;
b.foo = 'bar';
a.foo; // "bar";
答案 1 :(得分:0)
当您在this.counter += amount
中说add
时,this
指的是add
被调用的对象(在本例中为fido或maxx)。在这种情况下,+ =运算符从继承的值读取,因为counter
没有本地值并且写入新的本地值。因为fido或maxx现在拥有自己的计数器属性,所以原型被掩盖了。请尝试以下方法:
Dog.prototype = {
...
add : function(amount) {
Dog.prototype.counter += amount;
},
...
};