[英]Why does yielding a mutated object in a javascript generator result in different behavior when converted to array?
I have a generator function foo
written in JavaScript.我有一个用 JavaScript 编写的生成器 function foo
。
function* foo() {
const bar = { a: 0, b: 0 };
yield bar;
bar.a += 1;
yield bar;
bar.b += 10;
yield bar;
}
The function foo
takes no parameter but keeps an internal object bar
that is used for yielding. function foo
不带参数,但保留用于屈服的内部 object bar
。 The function can yield 3 times, each time returning a different value. function 可以产生 3 次,每次返回不同的值。
The expected behavior is observed when calling next().value
on the resulting object.在生成的 object 上调用next().value
时会观察到预期的行为。
const baz = foo()
console.log(baz.next().value) // => { a: 0, b: 0 }
console.log(baz.next().value) // => { a: 1, b: 0 }
console.log(baz.next().value) // => { a: 1, b: 10 }
However, when using the Array.from
method to create an array from the resulting iterator, a strange behavior is observed instead.但是,当使用Array.from
方法从生成的迭代器创建数组时,会观察到一种奇怪的行为。
console.log(Array.from(foo())) // => [ { a: 1, b: 10 }, { a: 1, b: 10 }, { a: 1, b: 10 } ]
The final object is returned for every yield instead of return the value each time yield
was called.最终的 object 为每个 yield 返回,而不是在每次调用yield
时返回值。 This behavior happens in both node 10.13 and node 12.7?这种行为发生在节点 10.13 和节点 12.7 中? Why is this happening?为什么会这样? Shouldn't the results be the same for both cases?两种情况的结果不应该相同吗?
Since in javascript objects are passed by reference you are modifying the same object after each yield and in the end you have an array with 3 references to the same object in memory in its final state. Since in javascript objects are passed by reference you are modifying the same object after each yield and in the end you have an array with 3 references to the same object in memory in its final state.
To get an array with different objects you would have to create new objects on each yield, for example using object spread syntax.要获得具有不同对象的数组,您必须在每个产量上创建新对象,例如使用 object 扩展语法。
function* foo() { let bar = { a: 0, b: 0 }; yield bar; bar = {...bar, a: bar.a + 1} yield bar; bar = {...bar, b: bar.b + 10} yield bar; } const baz = foo() console.log([...baz])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.