为什么默认情况下对象不可迭代?
我总是看到与迭代对象有关的问题,常见的解决方案是迭代对象的属性并以这种方式访问对象中的值。这似乎很常见,以至于我想知道为什么对象本身是不可迭代的。
默认情况下,对对象使用 ES6for...of
这样的语句会更好。因为这些特性只适用于不包含 {}
对象的特殊“可迭代对象”,所以我们必须克服一些困难才能使这些特性适用于我们想要使用它的对象。
语句的 for... of 创建一个循环,迭代 < strong > 迭代对象 (包括数组、映射、集合、参数对象等)。
例如,使用 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
这样的语句。另外,我想知道使对象可迭代是否允许将它们转换为 Array。
我试了下面的代码,但我得到了一个 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