句子"每次计算数组初始值设定项时,都会评估数组初始值设定项中的元素表达式"意思?

时间:2016-02-01 03:05:11

标签: javascript arrays

我正在阅读David Flanagan的JavaScript:The Definitive Guide,它可能是世界上最胖的JavaScript书籍。在简要描述数组初始化器时,Flanagan说"每次数组初始化器时都会计算数组初始值设定项中的元素表达式 被评估"。这意味着什么。我的练习结果让我更加困惑:

var a = 50;    
var b = 70;

var array = [a+b, 50];
console.log (array [0]);  //120

a = 60;
console.log (array [0]);  //120

var other = array;
console.log (other [0]);  //120

我认为在将值改为60之后结果将是130,因为表达式将被重新评估。但事实并非如此。我知道我完全弄错了。有人可以解释一下弗拉纳根试图在那句话中解释什么吗?

3 个答案:

答案 0 :(得分:2)

他的意思是,当数组文字表达式(" re&#34 ;-)被评估时,它的内容也是如此。

function makeArray() {
    return [a];
}
var a = 0;
console.log(makeArray()); // [0]
a = 1;
console.log(makeArray()); // [1]

所以,实际上没什么特别的,只是默认的表达行为。

答案 1 :(得分:1)

在这里,您将array分配给数组变量,它将存储该值,直到该变量(除非您修改该变量)超出范围。在第二个语句中,您将重用#34; array"所指向的相同数组。变量。第三个陈述只是将参考分配给"数组"变量到另一个变量并访问相同的元素。

仅第一次评估a + b语句,并将结果数组保存为值引用。最后一个语句是传递值的示例(Javascript总是按值传递),其中"数组"的副本变量创建为"其他"和"其他"也指向" array"指向的相同内存引用变量

答案 2 :(得分:1)

你错误引用了作者;他实际上说的是

  

每次计算数组初始值设定项时,都会计算数组初始化程序中的元素表达式。

而不是术语"数组初始化程序"如果他说"数组文字"它将更清晰,更符合常见用法。如果我们采用"阵列初始化器的常识解释"作为数组值变量"的含义"初始化器,那么这样的初始化器可以是数组文字,但也可以是任何数组表达式。 (话虽如此,似乎规范使用了术语"数组初始值设定项"用于"数组文字"在Section 12.2.5中,因此作者的用法不是这种技术意义上的错误。)另一方面,数组文字(基本上,形式为[...]的任何东西都可以用作初始化程序,但也可以在其他地方使用。

他似乎试图说的是一个数组文字,例如

[a]
每次重新评估自身时,

重新评估a,例如重新执行某个函数时。如果你考虑一下,这很明显。很难看出它如何以其他方式发挥作用。所以功能

function foo(x) { return [x]; }

将在调用[1]时返回数组foo(1),并在调用[2]时返回数组foo(2),因为数组文字[x]是每次调用函数时都会评估。

这与绊倒你的问题完全不同,即

var a = 22;
var b = [a];
a = 42;
console.log(b); 

更改b以获得值[42]。此行为与如何(重新)评估数组初始值设定项或(重新)评估其组件元素无关。与JavaScript变量和引用的工作方式有关。如果 bb的动态引用存储为其元素,则上述内容会更改a 的值,但JavaScript没有动态可更新的概念引用。换句话说,console.log(b)行确实正在评估b,但这只会返回b已经存在的内容。它不会(重新)评估最初用于设置[a]的表达式b。在设置b的值的语句之后,[a]碰巧对评估b产生的价值所带来的这一事实立即丢失,此时b现已拥有价值[22]

还要考虑以下示例,它完全类似于:

var a = 1, b = 2, c = a + b;
a = 42;
console.log(c);

此处,当c的值稍后更改时,没有人会期望作为a的初始值给出的表达式会发生变化。 c是3,它将一直显式重新分配。在console(c)行,是的,我们正在"评估" c,但这只是检索c的值,而不是重新评估过去曾经用于为c赋值的某些表达式。还有一些其他声明式语言范例,其中事物可能以这种方式表现,但不是JavaScript。