Как объект Javascript может стать итеративным с помощью for...of Statement?
Я хотел бы установить options[Symbol.iterator]
свойство для итерации на простых объектах, которые я создаю с for...of
заявление:
options = {
male: 'John',
female: 'Gina',
rel: 'Love'
};
for(let p of options){
console.log(`Property ${p}`);
};
Но этот код дает мне следующую ошибку:
array.html:72 Uncaught TypeError: options[Symbol.iterator] is not a function
Как я могу установить правильную функцию итератора для простого объекта, как указано выше?
решаемая
// define the Iterator for the options object
options[Symbol.iterator] = function(){
// get the properties of the object
let properties = Object.keys(this);
let count = 0;
// set to true when the loop is done
isDone = false;
// define the next method, need for iterator
let next = () => {
// control on last property reach
if(count >= properties.length){
isDone = true;
}
return {done:isDone, value: this[properties[count++]]};
}
// return the next method used to iterate
return {next};
};
И я могу использовать for...of
оператор на моем объекте теперь повторяемый:
for(let property of options){
console.log(`Properties -> ${property}`);
}
3 ответа
Использовать for...of
цикл вы должны определить соответствующий итератор для вашего объекта, используя [Symbol.iterator]
ключ.
Вот одна из возможных реализаций:
let options = {
male: 'John',
female: 'Gina',
rel: 'Love',
[Symbol.iterator]: function * () {
for (let key in this) {
yield [key, this[key]] // yield [key, value] pair
}
}
}
Хотя в большинстве случаев будет лучше перебирать объекты, используя обычный for...in
цикл вместо
В качестве альтернативы вы можете преобразовать ваш объект в итеративный массив, используя Object.keys
, Object.values
или же Object.entries
(ES7).
Если вы не хотите использовать синтаксис генератора, вы можете использовать другой способ определения функции итератора.
var options = {
male: 'John',
female: 'Gina',
rel: 'Love',
[Symbol.iterator]: function () {
var self = this;
var values = Object.keys(this);
var i = 0;
return {
next: function () {
return {
value: self[values[i++]],
done: i > values.length
}
}
}
}
};
for (var p of options) {
console.log(`Property ${p}`);
}
Простые объекты (options
в этом случае) не повторяются в ES6. Вам нужно либо определить итератор для вашего объекта, либо сделать что-то вроде:
for(let k of Object.keys(options)) {
console.log(`Property ${k}, ${options[k]}`);
};