Используя объекты для петель
почему нельзя использовать объекты в циклах for of? Или это ошибка браузера? Этот код не работает в Chrome 42, говоря, что undefined не является функцией:
test = { first: "one"}
for(var item of test) {
console.log(item)
}
13 ответов:
на для..из цикла поддерживает только итерируемые объекты, такие как массивы, а не объекты.
для перебора значений объекта, использовать:
for (var key in test) { var item = test[key]; }
если вы храните данные в хранилище ключ-значение, пожалуйста, используйте
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); });
Вы можете использовать следующий синтаксис:
let myObject = {first: "one"}; for(let [key, value] of Object.entries(myObject)) { console.log(key, value); // "first", "one" }
однако,
Object.entries
имеет плохую поддержку прямо сейчасне работает в IE или iOS Safari. Вам, вероятно, понадобится полифилл.
Я сделал объекты iterable с этим кодом:
Object.prototype[Symbol.iterator] = function*() { for(let key of Object.keys(this)) { yield([ key, this[key] ]) } }
использование:
for(let [ key, value ] of {}) { }
итератор, Iterable и for..цикла в ECMAScript 2015 / ES6
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
мы получаем ошибку, потому что для..из цикл работает только на Iterables, то есть объект, который имеет @@iterator это соответствует итератор протокол, что означает, что он должен иметь объект с далее метод. Следующий метод не принимает аргументов и возвращает объект с этими двумя свойствами.
сделал: сигналы о том, что последовательность закончилась, когда true и false означает, что может быть больше значений стоимостью: это текущий элемент в последовательности
Итак, чтобы сделать объект Iterable то есть, чтобы он работал с для..из можно:
1 .Сделайте объект Iterable назначая его мистическим @@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.Используйте
потому что литерал объекта не имеет символ.итератор собственность. Чтобы быть конкретным, вы можете только перебирать строка,массив,карта,Set,аргументы,NodeList(не широко поддерживает) и генератор С для...из петли.
чтобы иметь дело с итерацией литерала объекта, у вас есть два опции.
for...in
for(let key in obj){ console.log(obj[key]); }
ответа нет. Это не возможно использовать для..Из с объектными литералами.
Я согласен с Overv, что для..Of - это только для итераций. У меня был точно такой же вопрос, потому что я использовать объекты для перебора ключей и значений для..в. Но я просто понял, что на ES6 карты и наборы для.
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) и не необходимость использовать объект.ключи.)(
кроме того, ваши ключи не ограничивается строками. Вы можете использовать числа, объекты или другие литералы.
объектные литералы не имеют встроенных итераторов, которые необходимы для работы с
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]}`); } }
Как насчет использования
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.