开发者问题收集

Javascript - 迭代器混淆

2020-05-23
88

在此简单代码中,如果两次调用 console.log(names.next().value); ,则数组索引会增加。我不确定它是如何做到的,因为我认为它应该始终从 0 开始,因此它应该返回相同的值。

有人可以解释它是如何做到的吗?

// Iterator Example
function nameIterator(names) {
  let nextIndex = 0;
  console.log(nextIndex);

  return {
    next: function() {
      return nextIndex < names.length ? {
        value: names[nextIndex++],
        done: false
      } : {
        done: true
      }
    }
  }
}

// Create an array of names
const namesArr = ['Brad', 'Sara', 'John'];
// Init iterator and pass in the names array
const names = nameIterator(namesArr);

console.log(names.next().value);
console.log(names.next().value);
console.log(names.next().value);
console.log(names.next());

输出:

Brad
Sara
John
Object : {done: true}
3个回答

这是因为 next() 使用了 nameIterator() 函数中存在的 nextIndex 属性。

next() 没有可供其自身使用的 nextIndex 属性的单独副本。因此,当您在 next() 方法中执行 nextIndex++ 时,它实际上会更新我们在 nameIterator() 中拥有的 nextIndex ,并且下次调用 next() 时,您将仅访问这个更新的 nextIndex

chiragrtr
2020-05-23

这是因为代码中有以下一行。

names[nextIndex++]

此行选择 names 值中的索引,然后将 nextIndex 的值增加一,但只有在选择了键之后才会增加。请参阅下面的示例以查看其输出的内容。

let arr = [1, 2, 3];
let index = 0;

console.log(arr[index++]);
console.log(arr[index++]);
console.log(arr[index++]);
Emiel Zuurbier
2020-05-23

每次调用函数 next 时,索引都会增加 1 -> nextIndex++

您可以传递一个标志,表示您想要当前索引值,如下所示:

// Iterator Example
function nameIterator(names) {
  let nextIndex = 0;
  return {
    next: function(current) {      
      let index;
      if (current) {
        index = (nextIndex < names.length ? nextIndex : names.length) - 1;
      } else {
        index = nextIndex++;
      }
      
      return index < names.length ? {
        value: names[index],
        done: false
      } : {
        done: true
      }
    }
  }
}

// Create an array of names
const namesArr = ['Brad', 'Sara', 'John'];
// Init iterator and pass in the names array
const names = nameIterator(namesArr);

console.log(names.next().value);
console.log(names.next(true).value);
console.log(names.next(true).value);
console.log(names.next(true).value);
console.log(names.next().value);
console.log(names.next(true).value);
console.log(names.next().value);
console.log(names.next());
console.log(names.next(true).value);
console.log(names.next());
Ele
2020-05-23