在循环中赋值给变量之前评估右侧表达式

时间:2018-05-23 16:56:23

标签: javascript arrays list

我无法理解这个问题的答案:Making a list out of an Array

对于以下函数(从数组创建列表)

function arrayToList(array) 
{
  var list = null;
  for (var i = array.length-1; i>=0; i--) {
      list = {value: array[i], rest: list};
  }
  return list;
}

我的问题是:为什么新列表不会覆盖现有列表,而是将新列表替换为rest属性?

在对所选答案的评论中,解释说:

  

因为作业的整个右侧表达是   在实际分配给左手之前评估/执行   侧变量。因此,在构建新对象时,旧的   一个是未受影响的,所以它的价值可以在那期间使用   施工。就像var a = 1; a = 1 + a; a之后将是2,   在评估右侧之后,其值不会改变。   列表是一样的,我们不是编辑列表,我们正在改变它   是一个参考。即它是对{value: 3, rest: null}的引用   现在它是对新对象{value: 2, rest: {value: 3, rest: null}}的引用。

我无法理解这个答案,这意味着“在构造新物体时,旧物体不受影响,因此在此期间可以使用它的价值”。

这个循环如何表现为递归而不是连续重写列表?

2 个答案:

答案 0 :(得分:1)

  

为什么现有列表不会被新列表覆盖   而是将新列表替换为rest属性?

list = {value: array[i], rest: list};
//---------------------------^^^^^^

list对象会被覆盖,但由于上述原因,之前的值会在重新分配之前存储在rest中。

  

"在构建新对象时,旧对象不受影响   所以它的价值可以在那期间使用"。

为了理解目的,上述行可以解释如下

var temp = {value: array[i], rest: list};
list = temp;

如您所见,首先列表的先前值存储在对象的rest中,然后列表重新分配该对象。

答案 1 :(得分:0)

  

为什么新列表不会覆盖现有列表,而是将新列表替换为rest属性?

这是因为运算符和评估的优先级here you can find the precedence and the associativity,因此您必须首先解析{value: array[i], rest: list};,这意味着创建对象,存储值然后将其分配给{{ 1}}变量。

这种情况的一个例子如下:

list