在 JS 中的生成器上调用 join()

nas*_*-sh 8 javascript generator ecmascript-6

在 Python 中,您可以string.join()在任何可迭代对象上调用该方法,如下所示:

",".join(some_iterable)
Run Code Online (Sandbox Code Playgroud)

参数可以是列表、生成器或任何其他对象,只要它是可迭代的。

在玩 ES6 时,我找不到一种方法,而不必先创建一个数组,我不得不这样做:

function *myGenerator() { ... }
let output = [...myGenerator()].join(",");
Run Code Online (Sandbox Code Playgroud)

我知道这join()是一种Array.prototype方法。我是否可以调用join()或一些等效的方法来连接生成的值,myGenerator而不必创建中间数组,就像上面的 python 示例一样?

Mar*_*yer 7

上面的评论很好地回答了你的问题。然而,我对 @jonrsharpe 关于生成中间字符串的评论感到好奇,并且想知道这实际上如何影响性能。所以我join在生成器的原型上放置了一个方法并进行了测试。

这是join()代码:

function* nGen(start, stop) {
  while (start < stop) {
    yield start
    start++
  }
}

nGen.prototype.join = function(sep) {
  let res = this.next().value
  for (let v = this.next(); !v.done; v = this.next()) {
    res += sep + v.value
  }
  return res
}


let g = nGen(2, 20)

console.log(g.join(','))
Run Code Online (Sandbox Code Playgroud)

Safari 和 Chrome 中的原始 jsPerf 测试表明,这种方法比非常常见的习惯用法更快:[...g].join(',')。在 2022 年的 JSBench 测试中,Chrome、Firefox 和 Edge 之间的结果不一致,但这种方法现在比[...g].join(',')和/或for循环慢。

我距离编写 jsPerf/JSBench 测试的大师还很远,所以也许我搞砸了一些事情或误解了结果。但如果您感兴趣:https://jsbench.me/zlkz8tm6vw/1