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

标签 javascript function javascript-objects

MDN guide on working with objects的修订从 2014 年 7 月 15 日开始,状态:

If an object is created with an object initializer in a top-level script, JavaScript interprets the object each time it evaluates an expression containing the object literal.

但是,在下面的代码片段中,当 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();

最佳答案

objLit2 是顶级声明。因此,它会在您的脚本首次执行时进行评估。评估后,属性 objLit2.val2 将设置其值。除非您有意识地更改属性 objLit2.val2 的值,否则它不会因为您在代码中的其他地方引用 objLit2 而获得不同的值。

一旦 objLit2 被评估,属性 objLit2.val2 包含一个原始数字,它不再与变量 i 有任何联系。 objLit2.val2 的值独立存在,它的值不会受到任何其他变量更改的影响。

javascript 中的基元(如数字和 bool 值)存储为与任何其他变量无关的不同值。 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 文字中指定数组时,它只是存储对该数组的引用(而不是数组的单独副本)。如果您更改该原始数组,您将在包含对该数组的引用的所有其他变量中看到该更改。


您引用的内容听起来适用于在某个范围内(例如在函数内部)声明的对象,因为每次创建该范围时(例如每次运行函数时)都会重新评估它们。

关于javascript - 为什么每次读取属性时都不会重新评估对象初始值设定项中的表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24836259/

相关文章:

typescript - 具有多种类型的函数声明

Ruby 参数计数规则

javascript - 为什么 jQuery Extend Deep Copy 不递归复制对象?

Javascript从构造函数内部的函数调用原型(prototype)函数

javascript - 如何等待多个异步函数完成?

Python - 指定要在命令行上使用文件中的哪个函数

javascript - 将数据从 Native Activity 传递到 WebView

javascript - 寄生虫组合继承 : How does parent prototype's clone consist child prototype's property which has not been assigned yet?

javascript - 从同一类 div jquery 中查找不同的文本框值

javascript - 如何使用 json.ftl 获取 Alfresco 中关联对象的属性