【问题标题】:Javascript, instance property junkJavascript,实例属性垃圾
【发布时间】:2016-02-06 19:19:25
【问题描述】:

在下面的 Javascript 代码中,我创建了 2 个 Person 实例(p1p2)。

更改p1 的名称时,仅更改p1 的名称(而不是p2 的名称)。这正是我所期望的。

但是当更改p1.sizes.width 然后检查p2.sizes.width 的值时,似乎p1.sizes.width 等于p2.sizes.width

为什么?

var Person = {
  name: '',
  sizes: {width: {type:'size', value:undefined}, height: {type:'size', value:undefined}}
}

var p1 = Object.create(Person);
var p2 = Object.create(Person);

p1.name = "Alice";
p2.name = "Bob";

console.log(p1.name === "Alice") // true
console.log(p2.name === "Bob") // true

p1.sizes.width=20;

console.log(p1.sizes.width === 20) // true
console.log(p2.sizes.width === 20) // true (but I would had expected false...?!)

【问题讨论】:

    标签: javascript object prototype


    【解决方案1】:

    您正在为同一个对象创建一个委托链,而不是每次都实例化新版本的 Person。这意味着当 JIT 编译器查找属性大小(在 p1/p2 对象上未定义)时 - 它会上升到委托链中的下一个对象 - 在本例中为 Person - 因此它将修改 .sizes.width .对 names 属性无关紧要的原因是您正在覆盖单个实例上的该属性。如果您想要单独的实例化,请使用 new 关键字,即:

    var Person = function(){
      this.name = '',
      this.sizes = {width: {type:'size', value:undefined}, height: {type:'size', value:undefined}}
    }
    
    var p1 = new Person();
    var p2 = new Person();
    
    p1.name = "Alice";
    p2.name = "Bob";
    
    console.log(p1.name === "Alice") // true
    console.log(p2.name === "Bob") // true
    
    p1.sizes.width=20;
    
    console.log(p1.sizes.width === 20) // true
    console.log(p2.sizes.width === 20) // false
    

    你可以阅读更多herehere

    【讨论】:

    • 如果你愿意,你也可以用 Object.create 来做: var p1 = Object.create(Person.prototype);
    • 是的,你可以,但不是 OP 试图这样做的方式
    【解决方案2】:

    读取任何 javascript 对象的属性首先在对象的本地属性中查找命名属性。如果没有找到,则继续逐个查看原型链中的对象,寻找同名的属性,直到找到一个或原型链已用尽。如果找到,则返回原型链中属性的值。

    编写 javascript 对象的属性始终将其写入本地属性 - 原型链中相同命名属性的值不会更新。

    所以...

    Object.create(Person); 返回的对象的原始属性“名称”写入本地属性,一个值写入p1,另一个值写入p2

    写入p1.sizes.width=20; 但是首先需要通过尝试从p1 读取对象p1.sizes 来找到它的引用。读取返回Personsizes 属性,在原型链中找到,p1.sizesp2.sizes 的值相同。因为它们是同一个对象,所以写入它们是由p1p2 共享的。

    读取属性 - 如果需要,搜索原型链。

    写入属性 - 始终写入本地属性。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 2020-03-06
      • 1970-01-01
      • 1970-01-01
      • 2012-02-09
      • 1970-01-01
      • 2016-02-04
      相关资源
      最近更新 更多