1

谁能帮我理解为什么“计数器”属性似乎在每个新实例上都会重置?我希望它像“字母”属性一样工作,该属性在所有实例化对象中共享。

我在整理一些示例代码时遇到了这个问题,为什么应该以这种方式使用原型属性,除非它们是静态的。

示例代码:

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
4

2 回答 2

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 */

至于letters,这是按预期工作的,因为原型中的Objectpush上发生了- 您没有设置新的实例变量。如果您正在设置实例变量,它可能仍然有效,因为对象是通过引用分配给变量的,即

var a = {}, b = a;
b.foo = 'bar';
a.foo; // "bar";
于 2013-09-20T19:28:04.713 回答
0

当您说this.counter += amountin 时addthis指的是add被调用的对象(在本例中为 fido 或 maxx)。在这种情况下,+= 运算符从继承的值中读取,因为没有本地值,counter并且写入新的本地值。因为 fido 或 maxx 现在有自己的计数器属性,所以原型被掩盖了。尝试以下操作:

Dog.prototype = {

    ...

    add : function(amount) {
        Dog.prototype.counter += amount;
    },

    ...

};
于 2013-09-20T19:27:59.043 回答