【问题标题】:Javascript objects with number property in prototype原型中具有数字属性的Javascript对象
【发布时间】:2013-09-26 06:55:32
【问题描述】:

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

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

示例代码:

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

【问题讨论】:

  • 因为你的线路this.counter += amount实际上是在做this.counter = Dog.Prototype.counter + 1

标签: javascript prototype instance-variables javascript-objects


【解决方案1】:

这是因为线

this.counter += amount;

会发生什么? this.counter 没有在实例上找到属性 counter,所以它从 prototype 中获取它,但是当涉及到设置时,它会在实例上设置它 p>

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,这是按预期工作的,因为 push 正在原型中的 Object 上发生 - 您没有设置新的实例变量。如果您正在设置一个实例变量,它可能仍然有效,因为 Objects 是通过引用分配给变量的,即

var a = {}, b = a;
b.foo = 'bar';
a.foo; // "bar";

【讨论】:

  • 好答案;您应该说明为什么数组 letters 仍然在 Dog 的实例之间共享。
  • @NickHusher 我也按要求编辑了字母的解释。虽然我觉得没什么好说的,因为执行的动作完全不同。
  • 谢谢保罗!我怀疑柜台上的实例与原型范围,但阵列让我失望。我没有想到我是在数组上调用一个函数而不是直接设置它。
【解决方案2】:

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

Dog.prototype = {

    ...

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

    ...

};

【讨论】:

    猜你喜欢
    • 2011-12-17
    • 2020-06-21
    • 1970-01-01
    • 2013-04-09
    • 2015-07-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多