【问题标题】:Understanding Javascript's OOP: instances modifying other instances理解 Javascript 的 OOP:实例修改其他实例
【发布时间】:2010-12-27 20:58:52
【问题描述】:

我很难理解为什么修改实例a 中的属性会修改实例b 上的相同属性。

var A = function (){

};

A.prototype.data = {
    value : 0
};

var a = new A();
var b = new A();

console.log(a.data.value, b.data.value); // 0, 0
a.data.value = 5;
console.log(a.data.value, b.data.value); // 5, 5

prototype关键字不应该让data变量成为实例变量吗?

在这个按预期执行的示例中似乎不是这种情况:

var B = function (){
    this.data = {
        value : 0
    };
};

var i = new B();
var j = new B();

console.log(i.data.value, j.data.value); // 0, 0
i.data.value = 5;
console.log(i.data.value, j.data.value); // 5, 0

我很困惑为什么原型方法不起作用。也许我缺乏一些概念知识。

【问题讨论】:

    标签: javascript oop prototype


    【解决方案1】:

    因为它真的是这样做的:

    var A = function (){
    
    };
    
    var someObj = { value:0 };
    
    A.prototype.data = someObj;
    

    所以 A 的所有实例现在都有一个名为 data 的属性,它指向对象 someObj。在所有实例中,这是同一个对象。您正在更改该对象内的value。

    A 不拥有value。它包含对拥有value 的对象的引用。

    【讨论】:

      【解决方案2】:

      prototype关键字不应该让数据变量成为实例变量吗?

      恰恰相反。 A.prototype 由A 创建的所有对象共享。当您索引由A 创建的对象时,如果索引不存在,JavaScript 将尝试通过对象的原型(例如o.constructor.prototype)解析该索引。在这种情况下,您使用 data 对 a 和 b 进行索引,这在这些对象中不存在,因此它使用原型中的那个。

      【讨论】:

        【解决方案3】:

        js 中的原型是该类的所有实例之间共享的数据,它就像经典 oop 语言中的静态变量。有时将一些方法/字段放在 .prototype 中以节省运行时内存很有用。

        【讨论】:

          【解决方案4】:

          a 和b 具有相同的原型。所以他们的原型共享属性。这就是classical and prototypal inheritance 的区别。

          【讨论】:

            【解决方案5】:

            恰恰相反。原型在所有实例之间共享。 JavaScript 是一种原型语言,比经典的 OO 语言更通用。我很好的总结是 Prototypal inheritance。您还可以了解一些关于 io language 的知识,这是一种更“纯粹”的原型语言,可能有助于更好地理解 JavaScript。

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2012-05-30
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2022-08-02
              • 1970-01-01
              相关资源
              最近更新 更多