为什么默认情况下无法迭代对象?
我经常看到与迭代对象有关的问题,常见的解决方案是迭代对象的属性并以这种方式访问对象中的值。这似乎很常见,使我想知道为什么对象本身不可迭代。
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
Symbol.iterator
属性的东西都是可迭代的。因此,您只需要实现该属性即可。关于对象为何不可迭代的一种可能的解释可能是,这暗示着一切都是可迭代的,因为一切都是对象(当然,原语除外)。但是,遍历函数或正则表达式对象意味着什么?