Javascript 为什么每次读取属性时都不会重新计算对象初始值设定项中的表达式?

Javascript 为什么每次读取属性时都不会重新计算对象初始值设定项中的表达式?,javascript,function,javascript-objects,Javascript,Function,Javascript Objects,2014年7月15日起的修订版规定: 如果在顶级脚本中使用对象初始值设定项创建对象,则JavaScript每次计算包含对象文字的表达式时都会解释该对象 但是,在下面的代码段中,当计算objLit2.val2时,它不使用最后一个值集,该值集应为10和100;它使用1000,这是定义objLit2时声明的值。为什么会这样 var i=1000; 函数iPlus3(){ 警报(“iPlus3”); 返回i+3; } 变量objLit2={ val:iPlus3, val2:i=i+1 }; 函数se

2014年7月15日起的修订版规定:

如果在顶级脚本中使用对象初始值设定项创建对象,则JavaScript每次计算包含对象文字的表达式时都会解释该对象

但是,在下面的代码段中,当计算
objLit2.val2
时,它不使用最后一个值集,该值集应为
10
100
;它使用
1000
,这是定义
objLit2
时声明的值。为什么会这样

var i=1000;
函数iPlus3(){
警报(“iPlus3”);
返回i+3;
}
变量objLit2={
val:iPlus3,
val2:i=i+1
};
函数setValue(){
i=10;
log(“objLit2Val1”,objLit2.val(),objLit2.val2);//输出13 1001而不是13 11
i=100;
log(“objLit2Val2”,objLit2.val(),objLit2.val2);//输出103 1001而不是103 101
//如果在通话时解释'val',为什么每次通话时不解释'val2'?
}

setValue()
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
文本中指定数组时,它只是存储对该数组的引用(而不是数组的单独副本)。如果您更改原始数组,您将在包含对该数组的引用的所有其他变量中看到该更改



您所引用的内容将适用于在某个范围内(如在函数内)声明的对象,因为每次创建该范围时(例如每次运行函数时)都会重新计算这些对象。

在初始值设定项中,
i
递增一次,然后其值存储在
objLit2.val2
中。由于
i
是一个基本类型-一个数字-
objLit2。val2
是与
i
不同的变量

这与一个对象与另一个对象相等的情况相反

var objLit3 = objLit2;
objLit2.val2 = 5;
console.log(objLit2.val2); // Also 5

在这里的示例中,
objLit3
保存对同一基础对象的新引用,而不是创建新实例。数字不是这样的。每个分配了数字的新变量都是内存中的一个新实例。

当JavaScript创建对象文本时,键有一些值。该值可以是函数、数字等。。。在您的情况下,您正在提供一些要立即评估的值。。。例如,这在某种程度上等同于正在发生的事情:

var i = 1000;

function demo() {
    return i = i + 1;
}

var objLit2 = {
    val2: demo()
};

让我们逐步浏览代码的摘要版本。右边显示的是存储在每个语句变量中的内容

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
类型是。这意味着当一个对象(如
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

对于对象类型,请注意以下几点(这样做是因为它指定的是
对象
类型,而不是
编号
类型):


对于val2,它是存储的值(即1001),对于val,它是指向存储的函数的指针。当“JavaScript每次解释对象以计算表达式”objLit2时,1001仅保留为1001,但在两次调用中,该位置引用的函数值分别为13和103。
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;