在 ES9 中,我们可以使用 Object.values() 方法来获取一个对象中的所有值并以数组形式返回。这个方法虽然非常方便,但是在一些情况下使用它可能会导致生成器。
什么是生成器?
在讨论生成器之前,我们先来了解一下 JavaScript 中的迭代器。迭代器是一个具有 next()
方法的对象,每次调用 next()
方法都会返回一个对象,包含当前迭代的值和一个表示迭代是否结束的布尔值。例如:
const myIterator = { next: function () { return { value: 1, done: true } } } console.log(myIterator.next()) // { value: 1, done: true }
而生成器是一种能够暂停和恢复执行的函数。生成器通过 yield
语句来控制执行的流程。每次调用 yield
函数都会暂停当前的执行,直到下一次调用 next()
方法时,生成器会从上次暂停的地方继续执行。例如:
// javascriptcn.com 代码示例 function *myGenerator() { yield 1 yield 2 yield 3 } const myIterator = myGenerator() console.log(myIterator.next()) // { value: 1, done: false } console.log(myIterator.next()) // { value: 2, done: false } console.log(myIterator.next()) // { value: 3, done: false } console.log(myIterator.next()) // { value: undefined, done: true }
为什么使用 Object.values 会导致生成器?
在 ES9 中,我们可以使用 Object.values() 方法来获取一个对象中的所有属性值。例如:
const myObject = { a: 1, b: 2, c: 3 } console.log(Object.values(myObject)) // [1, 2, 3]
这个方法虽然非常方便,但是在一些情况下使用它可能会导致生成器。例如:
// javascriptcn.com 代码示例 function *myGenerator() { const myObject = { a: 1, b: 2, c: 3 } const myValues = Object.values(myObject) for (let value of myValues) { yield value } } const myIterator = myGenerator() console.log(myIterator.next()) // { value: 1, done: false } console.log(myIterator.next()) // { value: 2, done: false } console.log(myIterator.next()) // { value: 3, done: false } console.log(myIterator.next()) // { value: undefined, done: true }
在这个例子中,我们使用了 Object.values() 方法来获取一个对象的所有属性值,然后在生成器中一一输出。但是输出结果却与预期不同。实际上,生成器会输出一个类似 [object Generator]
的对象,这是因为 Object.values() 方法返回的是一个类数组对象,而它会默认拥有迭代器。所以当我们使用 Object.values() 方法时,它会自动将它的返回值转化成一个可迭代对象。
如何解决 Object.values 引发的问题?
如果 Object.values() 方法返回的是一个类数组对象,我们可以使用 Array.from() 方法将它转化成一个真正的数组。例如:
// javascriptcn.com 代码示例 function *myGenerator() { const myObject = { a: 1, b: 2, c: 3 } const myValues = Array.from(Object.values(myObject)) for (let value of myValues) { yield value } } const myIterator = myGenerator() console.log(myIterator.next()) // { value: 1, done: false } console.log(myIterator.next()) // { value: 2, done: false } console.log(myIterator.next()) // { value: 3, done: false } console.log(myIterator.next()) // { value: undefined, done: true }
这个方法虽然有些麻烦,但是它能够解决 Object.values() 方法所引发的问题。
总结
Object.values() 方法能够方便地获取一个对象中的所有属性值,但是在一些情况下使用它可能会导致生成器。如果遇到类似的问题,我们可以使用 Array.from() 方法将 Object.values() 方法返回的类数组对象转化成一个真正的数组。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/6585f5a0d2f5e1655d0728e2