原型中具有数字属性的Javascript对象

时间:2013-09-20 19:22:20

标签: javascript prototype instance-variables javascript-objects

任何人都可以帮助我理解为什么“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

2 个答案:

答案 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;
    },

    ...

};