Почему объекты по умолчанию не повторяются?
Я все время вижу вопросы, связанные с итерационными объектами, причем общее решение заключается в переходе по свойствам объекта и доступе к значениям внутри объекта таким образом. Это кажется настолько распространенным явлением, что это заставляет меня задаться вопросом, почему сами объекты не являются итерируемыми.
Заявления, подобные ES6 for...of, было бы неплохо использовать для объектов по умолчанию. Поскольку эти функции доступны только для специальных "итерируемых объектов", которые не включают объекты {}, нам нужно пройти через обручи, чтобы сделать эту работу для объектов, для которых мы хотим их использовать.
Оператор for... создает цикл, итерации по итерационным объектам(включая массив, карту, набор, объект аргументов и т.д.)...
Например, используя функцию генератора 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):

По умолчанию объекты {} не являются итерабельными, но почему? Разве недостатки перевешивают потенциальные выгоды от объектов, которые могут быть итерабельны? Какие проблемы связаны с этим?
Кроме того, поскольку объекты {} отличаются от коллекций "Array-like" и "итерируемых объектов", таких как NodeList, HtmlCollection и arguments, они не могут быть преобразованы в массивы.
Например:
var argumentsArray = Array.prototype.slice.call(arguments);
или использоваться с методами массива:
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