Javascript 同一个值的多个键 - 它们指向同一个地方吗?

Javascript multiple keys to the same value - Do they point to the same place?

我有以下简化代码:

var obj = {
    key1 : {
            aliases: ["alias1", "alias2"],
            prop1: someVal,
            prop2: someOtherVal
        }
}
var objHashMap = {};
for(var key in obj){
    objHashMap[key] = obj[key];
    objHashMap[obj[key].aliases[0]] = obj[key];
    objHashMap[obj[key].aliases[1]] = obj[key];
}

现在 objHashMap 有 3 个条目,所有条目都指向:

{
        aliases: ["alias1", "alias2"],
        prop1: someVal,
        prop2: someOtherVal
}

我的问题是 weather all 3 points to the same object, or points to 3 different copies of the object?

objHashMap.key1 将在 obj.key 中有一个 copy value。该值是对对象的引用。该值的两个副本都引用同一个对象。您使用 obj.key1.aliases[0]obj.key1.aliases[1] 的值创建两个附加属性,其中 具有引用的副本,引用同一对象。

在此之后:

var obj = {
    key1 : {
            aliases: ["alias1", "alias2"],
            prop1: someVal,
            prop2: someOtherVal
        }
}

...我们在内存中有这个:

                +----------------+
obj: ref-1654-->|    (object)    |
                +----------------+     +-------------------+
                | key1: ref-8754 |---->|     (object)      |
                +----------------+     +-------------------+     +-------------+
                                       | aliases: ref-6549 |---->|  (array)    |
                                       | prop1: ???        |     +-------------+
                                       | prop2: ???        |     | 0: "alias1" |
                                       +-------------------+     | 1: "alias2" |
                                                                 +-------------+

也就是说,我们有一个变量,obj,它包含一个值,告诉 JavaScript 引擎对象在内存中其他地方的位置;我已将其显示为上面的 ref-1654。将对象引用视为仅对 JavaScript 引擎有意义的数字,就像对大内存数组的索引。 (对象引用的实际值是我们永远看不到的。)

该对象有一个 属性、key1,它也有一个指向内存中其他地方的对象的值。该对象又具有 aliases 另一个 对内存中对象(这次是数组)的引用。 aliases 对象中 prop1prop2 的值未知(它们来自变量 someValsomeOtherVal,您还没有为它们定义我们)。

然后这一行添加另一个指向另一个对象的变量:

var objHashMap = {};
                       +----------------+
objHashMap: ref-8132-->|    (object)    |
                       +----------------+
                       |                |
                       +----------------+

您的 for-in 循环只针对键 "key1" 运行一次。第一行之后:

objHashMap[key] = obj[key];

我们有:

                +----------------+
obj: ref-1654-->|    (object)    |
                +----------------+          
                | key1: ref-8754 |---------+
                +----------------+         |
                                           |
                                           |
                                           |   +-------------------+                 
                                           +-->|     (object)      |                 
                                           |   +-------------------+     +-------------+
                                           |   | aliases: ref-6549 |---->|  (array)    |
                       +----------------+  |   | prop1: ???        |     +-------------+
objHashMap: ref-8132-->|    (object)    |  |   | prop2: ???        |     | 0: "alias1" |
                       +----------------+  |   +-------------------+     | 1: "alias2" |
                       | key1: ref-8754 |--+                             +-------------+
                       +----------------+

请注意新对象中的 key1 属性 如何包含与 key1 属性 中的 相同的值原始对象。他们指向同一个对象。

然后你做:

objHashMap[obj[key].aliases[0]] = obj[key];

...也就是说

objHashMap[obj.key1.aliases[0]] = obj[key];

...因为key包含"key1",也就是说

objHashMap["alias1"] = obj[key];

...因为 obj.key1.aliases[0]"alias1"。这给了我们:

                +----------------+
obj: ref-1654-->|    (object)    |
                +----------------+          
                | key1: ref-8754 |-----------+
                +----------------+           |
                                             |
                                             |
                                             |    +-------------------+                 
                                             ++-->|     (object)      |                 
                                             ||   +-------------------+     +-------------+
                                             ||   | aliases: ref-6549 |---->|  (array)    |
                       +------------------+  ||   | prop1: ???        |     +-------------+
objHashMap: ref-8132-->|     (object)     |  ||   | prop2: ???        |     | 0: "alias1" |
                       +------------------+  ||   +-------------------+     | 1: "alias2" |
                       | key1:   ref-8754 |--+|                             +-------------+
                       | alias1: ref-8754 |---+ 
                       +------------------+

然后再为这一行:

objHashMap[obj[key].aliases[1]] = obj[key];

...即:

objHashMap["alias2"] = obj[key];

...因为 obj.key1.aliases[1]"alias2"。所以我们最终得到:

                +----------------+
obj: ref-1654-->|    (object)    |
                +----------------+          
                | key1: ref-8754 |-----------+
                +----------------+           |
                                             |
                                             |
                                             |    +-------------------+                 
                                             +++->|     (object)      |                 
                                             |||  +-------------------+     +-------------+
                                             |||  | aliases: ref-6549 |---->|  (array)    |
                       +------------------+  |||  | prop1: ???        |     +-------------+
objHashMap: ref-8132-->|     (object)     |  |||  | prop2: ???        |     | 0: "alias1" |
                       +------------------+  |||  +-------------------+     | 1: "alias2" |
                       | key1:   ref-8754 |--+||                            +-------------+
                       | alias1: ref-8754 |---+|
                       | alias2: ref-8754 |----+ 
                       +------------------+

是的,它们指向同一个对象。让我举个例子来证明这一点:

  var obj = {
      key1 : {
              aliases: [1,2],
              prop1: 3,
              prop2: 4
          }
  }
  //initialize another object which will contain the same values.
  var objHashMap = {};
  for(var key in obj){
      objHashMap[key] = obj[key];
      objHashMap[obj[key].aliases[0]] = obj[key];
      objHashMap[obj[key].aliases[1]] = obj[key];
  }
  //change the value of a key in objHashMap.
  objHashMap["key1"].prop1 = 600
  //now observe the value changed in other keys as well.
  console.log(objHashMap[1].prop1);
  console.log(objHashMap[2].prop1);
  console.log(obj);