为什么默认情况下对象不可迭代?
我总是看到与迭代对象相关的问题,常见的解决方案是迭代对象的属性并以这种方式访问对象内的值。这似乎很常见,以至于我想知道为什么对象本身不可迭代。
for...of
默认情况下,像 ES6这样的语句很适合用于对象。因为这些功能仅适用于不包含{}
对象的特殊“可迭代对象” ,所以我们必须通过一些障碍来使这项功能适用于我们想要使用它的对象。
for...of 语句创建一个循环迭代可迭代对象 (包括 Array、Map、Set、arguments 对象等)...
例如使用 ES6生成器函数:
var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};
function* entries(obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
}
for (let [key, value] of entries(example)) {
console.log(key);
console.log(value);
for (let [key, value] of entries(value)) {
console.log(key);
console.log(value);
}
}
当我在 Firefox(支持ES6)中运行代码时,上面按照我期望的顺序正确记录数据:
默认情况下,{}
对象不可迭代,但为什么呢?缺点是否会超过对象可迭代的潜在好处?与此相关的问题是什么?
此外,由于{}
对象不同于“类数组”集合和“可迭代对象”,例如NodeList
、HtmlCollection
、 和arguments
,因此它们无法转换为数组。
例如:
var argumentsArray = Array.prototype.slice.call(arguments);
或与 Array 方法一起使用:
Array.prototype.forEach.call(nodeList, function (element) {})
.
除了我上面的问题,我很想看到一个关于如何将{}
对象变成可迭代的工作示例,尤其是那些提到[Symbol.iterator]
. 这应该允许这些新的{}
“可迭代对象”使用像for...of
. 另外,我想知道使对象可迭代是否允许将它们转换为数组。
我尝试了下面的代码,但我得到了一个TypeError: can't convert undefined to object
.
var example = {a: {e: 'one', f: 'two'}, b: {g: 'three'}, c: {h: 'four', i: 'five'}};
// I want to be able to use "for...of" for the "example" object.
// I also want to be able to convert the "example" object into an Array.
example[Symbol.iterator] = function* (obj) {
for (let key of Object.keys(obj)) {
yield [key, obj[key]];
}
};
for (let [key, value] of example) { console.log(value); } // error
console.log([...example]); // error