【问题标题】:Passing value to Symbol.iterator将值传递给 Symbol.iterator
【发布时间】:2015-12-09 07:29:37
【问题描述】:

如果我为一个对象定义一个迭代器并创建一个实例,我可以像预期的那样对这些值进行迭代:

class Hello {
  *[Symbol.iterator]() {
    yield 5;
   }
  *iterator (value) {
    yield value;
  }
}

var hello = new Hello();

for (let val of hello) {
  console.log(val); // 5
}

for (let val of hello.iterator('wow')) {
  console.log(val); // 'wow'
}

在前面的示例中,[Symbol.iterator] 被声明为生成器。我可以声明另一个生成器并将参数传递给它,但是有没有办法将参数传递给默认迭代器?

我尝试了以下方法,但它引发了错误:

for (let val of hello('wow')) {
  console.log(val); // 5
}

// Uncaught TypeError: hello is not a function

我错过了什么吗?或者这是不可能的?

【问题讨论】:

    标签: javascript generator ecmascript-6


    【解决方案1】:

    当你在for…of循环中传递一个要迭代的值时,它需要实现iterable接口——也就是说,它的Symbol.iterator方法将被隐式调用,不带参数,应该返回一个迭代器。

    您也可以直接传递迭代器,因为所有迭代器都是“可迭代的”,它们的Symbol.iterator 方法只会返回它们自己。

    所以虽然没有办法让for…of 循环调用带有特殊参数的默认迭代器,但您始终可以自己调用该方法并传递迭代器:

    var hello = {
      *[Symbol.iterator](val) {
        yield val;
      }
    };
    for (let val of hello[Symbol.iterator]('works')) {
      console.log(val); // 'works'
    }
    

    【讨论】:

    • 这真的很难看,但它完全回答了我的问题。谢谢!
    • 我看不出它有多丑——它和你原来的 .iterator 方法调用一样。但我想知道无论如何为什么你这样做,也许这就是为什么感觉难看?
    • 我正在制作一个类似于 API 的图形,您可以在其中迭代所有节点(包括孤儿)或将一个节点传递给迭代器,并且只传递相邻节点的迭代器。在我看来,这将是默认行为是有道理的,但是由于这种语法(并且仅因为这种语法!),我将只创建另一个迭代器,您必须在其中传递一个节点。无论如何,这不是一个糟糕的解决方案。
    • 是的,这确实应该是两种不同的方法。顺便说一句,本机 Map API 有一个默认的 [Symbol.iterator]() 方法,也可以作为 .entries() 访问。
    猜你喜欢
    • 2014-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多