我正在阅读Eloquent JavaScript练习部分,并且在本书中的以下代码遇到了问题:
function arrayToList(array) {
let list = null;
for (let i = array.length - 1; i >= 0; i--) {
list = {value: array[i], rest: list};
}
return list;
}
console.log(arrayToList([10, 20]));
// → {value: 10, rest: {value: 20, rest: null}}
首先,我不了解console.log
如何获得该输出。我尤其对list = {value: array[i], rest: list};
部分感到困惑。我确实知道在第一次迭代中,array[i]
等于20
,因此列表现在为{value: 20, rest: null}
。在第二个迭代中,array[i]
是10
,因此列表现在是{value: 10, rest: list}
,并且list
引用了{value: 20, rest: null}
,因此我们有list = {value: 10, rest: {value: 20, rest: null}}
。我的理解正确吗?如果是这样,我感到非常困惑,list
在被分配时如何仍能记住它先前包含的值,即{value: 20, rest: null}
。有人可以解释一下吗?
第二,我不明白为什么它提到了:
'从头到尾完成列表的创建会更容易。所以arrayToList 可以向后遍历数组(请参阅上一练习) 并将每个元素添加到列表中。您可以使用本地 绑定以保存到目前为止构建的列表部分,并使用 像list = {value:X,rest:list}这样的赋值来添加元素。'
为什么从头到尾建立清单更容易?但是,从前到后完成时是否可以建立列表?
第三,当我尝试将上面的代码更改为以下代码时:
function arrayToList(...array) { //Only change is from array to ...array
let list = null;
for (let i = array.length - 1; i >= 0; i--) {
list = {value: array[i], rest: list};
}
return list;
}
console.log(arrayToList([10, 20]));
// → {value: [10, 20], rest: null} Why did the output change?
答案 0 :(得分:1)
在第二个版本中使用扩展语法时,是说您希望将函数的所有参数收集到一个数组(称为“数组”)中。当您实际上调用函数时,您传递了一个单参数:数组[10, 20]
。因此,在函数中,array
将是[[10, 20]]
—一个以该数组作为其单个元素的数组。因此,该循环只会进行一次迭代。
如果您要使用来调用第二个版本功能
console.log(arrayToList(10, 20))
您将获得的结果与您在第一个代码示例中获得的结果非常相似。函数中的“ array”参数将是两个 个值的数组10
和20
。
关于“表达式”是什么的问题,这是一种语法构造,很容易直观地“获得”,但是(特别是在JavaScript中)在细节上相当复杂。基本上,诸如数学(代数)结构,比较,甚至单个变量引用或函数调用之类的东西都是表达式。 statement 只能由一个(可能是大)表达式组成,但语句也可以是for
循环,var
或let
声明,return
语句以及其他各种内容。 JavaScript语法通常会引入带有特定关键字的语句,对于表达式语句, 除外。