2014年7月15日对MDN guide on working with objects的修订声明:
如果在顶级脚本中使用对象初始值设定项创建对象,则JavaScript每次评估包含对象文字的表达式时都会解释该对象。
但是,在下面的代码段中,评估objLit2.val2
时,它不会使用最后一个值10
和100
;它改为使用1000
,它是定义objLit2
时声明的值。为什么会这样?
var i = 1000;
function iPlus3() {
alert("iPlus3");
return i + 3;
}
var objLit2 = {
val: iPlus3,
val2: i = i + 1
};
function setValue() {
i = 10;
console.log("objLit2Val1", objLit2.val(), objLit2.val2); // Outputs 13 1001 and not 13 11
i = 100;
console.log("objLit2Val2", objLit2.val(), objLit2.val2); // Outputs 103 1001 and not 103 101
// If `val` is interpreted at the time of the call, why is `val2` not also interpreted on each call?
}
setValue();

答案 0 :(得分:2)
objLit2
是一个顶级声明。因此,它会在您的脚本首次执行时进行评估。评估后,属性objLit2.val2
将设置其值。除非您有意识地更改属性objLit2.val2
的值,否则它不会因为您在代码中的其他位置引用objLit2而获得不同的值。
评估objLit2
后,属性objLit2.val2
包含一个原始数字,该数字不再与变量i
有任何关联。 objLit2.val2
的值独立存在,其值不会受到任何其他变量的影响。
javascript中的原语(如数字和布尔值)存储为不与任何其他变量连接的不同值。 javascript中的对象存储为对原始对象的引用。由于objLit2.val2
是一个数字,它只是一个独立的值,它独立存在。
所以,你可以这样做:
var i = 1000;
var objLit2 = { val : iPlus3, val2 : i = i + 1 };
console.log(objLit2.val2); // shows 1001
i += 1000;
console.log(objLit2.val2); // still shows 1001
另一方面,对象存储为对原始对象的引用。所以,如果你这样做了:
var indexes = [1,2,3];
var objLit2 = { val : indexes, val2 : i = i + 1 };
console.log(objLit2.indexes); // shows [1,2,3]
indexes[0] = 0;
console.log(objLit2.indexes); // shows [0,2,3]
因为数组是一个对象所以当你在objLit2
文字中指定数组时,它只是存储对该数组的引用(而不是数组的单独副本)。如果更改原始数组,您将在包含对该数组的引用的所有其他变量中看到该更改。
您所引用的内容将适用于在某个范围内声明的对象(如函数内部),因为每次创建范围时都会重新评估它们(例如,每次运行该函数时)。
答案 1 :(得分:1)
在初始值设定项中,i
递增一次,然后将其值存储在objLit2.val2
中。由于i
是基本类型 - 数字 - objLit2.val2
是与i
不同的变量。
这与一个对象设置为另一个对象的情况形成对比。
var objLit3 = objLit2;
objLit2.val2 = 5;
console.log(objLit2.val2); // Also 5
在此处的示例中,objLit3
将新的引用保存到同一个基础对象,而不是创建新的实例。数字不会发生这种情况。分配了数字的每个新变量都是内存中的新实例。
答案 2 :(得分:0)
当JavaScript创建对象文字时,该键具有一些值。这个值可能是一个函数,数字等等......在你的情况下,你需要立即提供一些值来评估价值...例如,这有点等同于发生的事情:< / p>
var i = 1000;
function demo() {
return i = i + 1;
}
var objLit2 = {
val2: demo()
};
答案 3 :(得分:0)
让我们逐步完成代码的摘要版本。右边显示的是每个语句中变量中存储的内容。
var i = 1000; // i = 1000
var objLit2 = { val: iPlus3, val2: i = i + 1 }; // i = 1001, objLit2.val2 = 1001
i = 10; // i = 10, objLit2.val2 = 1001
innerHTML = (i + 3).toString() + ' ' + '1001'; // Outputs: 13 1001
i = 100; // i = 100, objLit2.val2 = 1001
innerHTML = (i + 3).toString() + ' ' + '1001'; // Outputs: 103 1001
您似乎认为语句val2 : i = i + 1
表示对i
的引用已分配给val2
。但javascript中的number
类型不是 immutable 。这意味着当一个对象(如i
和objLit2
)被赋予一个数字时,它将始终存储该数字的值而不是参考。
例如:
var i, val2;
i = 1000; // i = 1000
i = i + 1; // i = 1001
val2 = i; // i = 1001, val2 = 1001
val2++; // i = 1001, val2 = 1002
请注意以下对象类型(以这种方式工作,因为它分配的是object
类型,而不是number
类型):
var objectType = { numType: 14 }, // objectType = { numType: 14 }
otherObject = objectType; // otherObject = &objectType; (reference to)
// So the following statement...
otherObject.numType = 15; // objectType = { numType: 15 };
// ...is equivalent to: // otherObject = &objectType; (reference to)
objectType.numType = 15;
// since:
otherObject == objectType;