【问题标题】:I don't understand: for (var node = list; node; node = node.rest)我不明白: for (var node = list; node; node = node.rest)
【发布时间】:2020-06-29 19:52:52
【问题描述】:

下面的练习基于“Eloquent Javascript”一书。 listToArray 函数接受一个链表(或一组嵌套的对象)作为参数。我无法想象这个函数中的 for 循环是如何工作的。为什么条件只是“节点”?

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

function listToArray(list) {
  var array = [];
  for (let node = list; node; node = node.rest) {
    array.push(node.value);
  }
  return array;
}

console.log(arrayToList([10, 20]));
// → {value: 10, rest: {value: 20, rest: null}}
console.log(listToArray(arrayToList([10, 20, 30])));
// → [10, 20, 30]

【问题讨论】:

  • 条件在node 为真时运行。一旦node.rest 为假,循环结束。
  • for 的第二部分是要测试的条件,以查看是否应该执行循环的另一次迭代。当使用单个值时(此处为node),它只计算变量并将其转换为布尔值。如果结果是true,则循环再次进行。如果false 没有
  • 在这种情况下,将node 作为条件与写node != null 基本相同。
  • @Lain 不完全是。它运行 nodetruthy (不是“truesy”)。它运行直到 nodefalsy
  • @Lain 你写了“truesy”。

标签: javascript


【解决方案1】:

是的,你是对的,条件是node。但这就像

if (node) {
    doSomething();
}

它检查 node 是否“已定义”(不是 undefinednull

所以让我们一步一步地看这个例子:

  1. node = {value: 10, rest: {value: 20, rest: null}}10 (value) 被推送到 array
  2. node = {value: 20, rest: null},因为新的node是旧noderest20 被推送到 array
  3. node = null → 此处停止,因为条件 (node === undefined) 不满足

【讨论】:

  • 其实是node !== null
  • @Barmar:其实是!!node
  • @knittl 在这个算法中,node 要么是一个对象,要么是null。因此,虽然还有其他方式可以更一般地表达条件,但这里重要的是node !== null 是否为真。答案是倒过来的(上面写着===),指的是undefined
【解决方案2】:

我个人认为node 之类的条件是模棱两可的,可能会导致意想不到的行为,而且没有什么好处。

本质上,条件实际上是node != null,因为那是另一个函数的种子值。我建议在您编写的任何代码中明确说明这一点。例如,对于像 Go 这样的语言,条件只允许使用布尔值。这可以使代码更具可读性,虽然可能不像“高尔夫球”。

【讨论】:

  • 我支持这个。维护代码并且不确定某些功能是有意的还是偶然的,这很糟糕。
  • 嗯,其实这个条件其实就是!!node,就是检验值是否为真。这个条件可以被几个不同的值拒绝:false、0、空字符串、null 和 undefined。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-01-05
  • 2020-08-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多