MDN表示:
yield关键字导致对生成器的next((方法的调用返回具有两个属性的IteratorResult对象:value和done。value属性是计算yield表达式的结果,done为false,表示生成器函数尚未完全完成。
我在Chrome 91.0.4472.77中运行了一个测试,每次它似乎都是一个新对象。如果处理是细粒度的(迭代次数多,每次计算量低(,这似乎是非常浪费的。为了避免不可预测的吞吐量和GC jank,这是不可取的。
为了避免这种情况,我可以定义一个迭代器函数,在这里我可以控制(确保(每个next()
对{value, done}
对象的重用,从而使属性值被修改到位,即没有为新的{value, done}
对象分配内存。
我是错过了什么,还是发电机天生就有产生垃圾的天性?如果我所做的只是const {value, done} = generatorObject.next();
,即我不可能获得对象的句柄,即引擎没有理由分配新的对象,那么哪些浏览器足够聪明,不会分配新的{value, done}
对象?
ECMAScript规范要求生成器为每个产量分配一个新对象,因此所有兼容的JS引擎都必须这样做。
理论上,如果JS引擎能够证明程序的可观察行为不会因为这种优化而改变,例如当生成器的唯一用途是在const {value, done} = generatorObject.next()
语句中时,那么它就有可能重用生成器的结果对象。然而,我不知道有任何引擎(至少是流行的网络浏览器中使用的引擎(可以做到这一点。像这样的优化在JavaScript中是一个非常困难的问题,因为它具有动态特性。