Почему нельзя использовать объекты в циклах for? Или это ошибка браузера? Этот код не работает в Chrome 42, говоря, что undefined не является функцией:
test = { first: "one"}
for(var item of test) {
console.log(item)
}
javascript
for-loop
ecmascript-6
iterable
Даниэль Херр
источник
источник
Ответы:
Цикл for..of поддерживает только итерируемые объекты, такие как массивы, но не объекты.
Чтобы перебрать значения объекта, используйте:
for (var key in test) { var item = test[key]; }
источник
.iterable
функции-члена, из-за которой возникает ошибка, когда вы пытаетесь использовать ее для объекта (у которого ее нет). developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…if (test.hasOwnProperty(key)){ ... }
? Или это не нужно?Вы можете использовать этот синтаксис:
let myObject = {first: "one"}; for(let [key, value] of Object.entries(myObject)) { console.log(key, value); // "first", "one" }
Тем не мение,
Object.entries
имеет плохую поддержку прямо сейчасне работает в IEили iOS Safari. Ты будешьвероятноможет понадобиться полифилл.источник
Если вы храните данные в хранилище "ключ-значение", используйте то,
Map
что специально предназначено для этой цели.Если вам нужно использовать объект, ES2017 (ES8) позволяет вам использовать
Object.values
:const foo = { a: 'foo', z: 'bar', m: 'baz' }; for (let value of Object.values(foo)) { console.log(value); }
Если это еще не поддерживается, используйте polyfill: Альтернативная версия для
Object.values()
И, наконец, если вы поддерживаете более старую среду, которая не поддерживает этот синтаксис, вам придется прибегнуть к использованию
forEach
иObject.keys
:var obj = { a: 'foo', z: 'bar', m: 'baz' }; Object.keys(obj).forEach(function (prop) { var value = obj[prop]; console.log(value); });
источник
Object.entries
можно полифиллировать, не касаясь прототипа.for-in
?let tempArray = [1,2,3,4,5]; for(element of tempArray) { console.log(element); } // 1 // 2 // 3 // 4 // 5
Но если мы это сделаем
let tempObj = {a:1, b:2, c:3}; for(element of tempObj) { console.log(element); } // error
Мы получаем ошибку, потому что цикл for..of работает только с Iterables , то есть с объектом, который имеет итератор @@, который придерживается протокола Iterator , что означает, что он должен иметь объект со следующим методом. Следующий метод не принимает аргументов и должен возвращать объект с этими двумя свойствами.
done : сигнализирует, что последовательность завершена, когда true, а false означает, что может быть больше значений value : это текущий элемент в последовательности
Итак, чтобы сделать объект Iterable, то есть заставить его работать с for..of, мы можем:
1. Сделайте объект Iterable , назначив ему мистическое свойство @@ iterator через свойство Symbol.iterator. Вот как:
let tempObj = {a:1, b:2, c:3}; tempObj[Symbol.iterator]= () => ({ next: function next () { return { done: Object.keys(this).length === 0, value: Object.keys(this).shift() } } }) for(key in tempObj){ console.log(key) } // a // b // c
2.Use Object.entries , который возвращает Iterable :
let tempObj = {a:1, b:2, c:3}; for(let [key, value] of Object.entries(tempObj)) { console.log(key, value); } // a 1 // b 2 // c 3
3. Используйте Object.keys , вот как:
let tempObj = {a:1, b:2, c:3}; for (let key of Object.keys(tempObj)) { console.log(key); } // a // b // c
Надеюсь это поможет!!!!!!
источник
Я сделал объекты повторяемыми с помощью этого кода:
Object.prototype[Symbol.iterator] = function*() { for(let key of Object.keys(this)) { yield([ key, this[key] ]) } }
Применение:
for(let [ key, value ] of {}) { }
Альтернативно:
for(let [ key, value ] of Object.entries({})) { }
источник
Поскольку литерал объекта не имеет свойства Symbol.iterator . Чтобы быть конкретным, вы можете перебирать String , Array , Map , Set , arguments , NodeList (широко не поддерживается) и Generator с помощью цикла for ... of .
Чтобы справиться с итерацией Object Literal, у вас есть два варианта.
для ... в
for(let key in obj){ console.log(obj[key]); }
Object.keys + forEach
Object.keys(obj).forEach(function(key){ console.log(obj[key]); });
источник
Ответ - нет. Использовать For..Of с литералами Object невозможно.
Я согласен с Overv, что For..Of предназначен только для итераций. У меня был точно такой же вопрос, потому что я использую объекты для перебора ключей и значений с помощью for..in. Но я только что понял, что для этого нужны ES6 MAPS и SETS .
let test = new Map(); test.set('first', "one"); test.set('second', "two"); for(var item of test) { console.log(item); // "one" "two" }
Следовательно, достигается цель, заключающаяся в том, что не нужно использовать for..In (проверка с помощью hasOwnProperty ) и не использовать Object.keys ().
Кроме того, ваши ключи не ограничиваются строками. Вы можете использовать числа, объекты или другие литералы.
источник
У объектных литералов нет встроенных итераторов, необходимых для работы с
for...of
циклами. Однако, если вы не хотите мучиться с добавлением собственного[Symbol.iterator]
к вашему объекту, вы можете просто использовать этотObject.keys()
метод. Этот метод возвращаетArray
объект, у которого уже есть встроенный итератор, поэтому вы можете использовать его с такимfor...of
циклом:const myObject = { country: "Canada", province: "Quebec", city: "Montreal" } for (let i of Object.keys(myObject)) { console.log("Key:", i, "| Value:", myObject[i]); } //Key: country | Value: Canada //Key: province | Value: Quebec //Key: city | Value: Montreal
источник
Можно определить итератор для любого передающего объекта, таким образом вы можете поместить различную логику для каждого объекта.
var x = { a: 1, b: 2, c: 3 } x[Symbol.iterator] = function* (){ yield 1; yield 'foo'; yield 'last' }
Затем просто повторите итерацию
x
for (let i in x){ console.log(i); } //1 //foo //last
Можно сделать то же самое с
Object.prototype
объектом и иметь общий итератор для всех объектовObject.prototype[Symbol.iterator] = function*() { for(let key of Object.keys(this)) { yield key } }
затем повторите свой объект следующим образом
var t = {a :'foo', b : 'bar'} for(let i of t){ console.log(t[i]); }
Или так
var it = t[Symbol.iterator](), p; while(p = it.next().value){ console.log(t[p]) }
источник
Я просто сделал следующее, чтобы легко утешить свои вещи.
for (let key in obj) { if(obj.hasOwnProperty(key){ console.log(`${key}: ${obj[key]}`); } }
источник
Как насчет использования Object.keys для получения массива ключей? А затем forEach в массиве ?
obj = { a: 1, b:2} Object.keys(obj).forEach( key => console.log(`${key} => ${obj[key]}`))
источник
Как насчет использования
function* entries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } for ([key, value] of entries({a: "1", b: "2"})) { console.log(key + " " + value); }
источник
в ES6 вы можете использовать генератор:
var obj = {1: 'a', 2: 'b'}; function* entries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } let generator = entries(obj); let step1 = generator.next(); let step2 = generator.next(); let step3 = generator.next(); console.log(JSON.stringify(step1)); // {"value":["1","a"],"done":false} console.log(JSON.stringify(step2)); // {"value":["2","b"],"done":false} console.log(JSON.stringify(step3)); // {"done":true}
Вот файл jsfiddle. В выходе вы получите объект с
"value"
и"done"
ключами."Value"
содержит все, что вы хотите , и"done"
текущее состояние итерации в bool.источник
Используя Array Destruction, вы можете выполнить итерацию следующим образом, используя
forEach
const obj = { a: 5, b: 7, c: 9 }; Object.entries(obj).forEach(([key, value]) => { console.log(`${key} ${value}`); // "a 5", "b 7", "c 9" });
источник