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
对象中 prop1
和 prop2
的值未知(它们来自变量 someVal
和 someOtherVal
,您还没有为它们定义我们)。
然后这一行添加另一个指向另一个对象的变量:
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);
我有以下简化代码:
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
对象中 prop1
和 prop2
的值未知(它们来自变量 someVal
和 someOtherVal
,您还没有为它们定义我们)。
然后这一行添加另一个指向另一个对象的变量:
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);