Почему объекты по умолчанию не повторяются?
Я все время вижу вопросы, связанные с итерационными объектами, причем общее решение заключается в переходе по свойствам объекта и доступе к значениям внутри объекта таким образом. Это кажется настолько распространенным явлением, что это заставляет меня задаться вопросом, почему сами объекты не являются итерируемыми.
Заявления, подобные 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