Используя объекты для петель


почему нельзя использовать объекты в циклах for of? Или это ошибка браузера? Этот код не работает в Chrome 42, говоря, что undefined не является функцией:

test = { first: "one"}

for(var item of test) {
  console.log(item)
}
13 63

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.

Как насчет использования