How can a Javascript object become iterable with f

2020-05-26 03:40发布

问题:

I would like to set the options[Symbol.iterator] property in order to iterate on the simple objects I create with the for...of statement :

options = {
  male: 'John',
  female: 'Gina',
  rel: 'Love'
};


for(let p of options){
  console.log(`Property ${p}`);
};

But this code gives me the following error:

 array.html:72 Uncaught TypeError: options[Symbol.iterator] is not a function

How I can set the right iterator function on a simple object as above?

Solved

 // 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};
  };

And I can use the for...of statement on my object now iterable :

 for(let property of options){
   console.log(`Properties -> ${property}`);
 }

回答1:

To use for...of loop you should define an appropriate iterator for your object using [Symbol.iterator] key.

Here is one possible implementation:

let options = {
  male: 'John',
  female: 'Gina',
  rel: 'Love',
  [Symbol.iterator]: function * () {
    for (let key in this) {
      yield [key, this[key]] // yield [key, value] pair
    }
  }
}

Though, in most cases it'll be better to iterate over objects using plain for...in loop instead.

Alternatively you could convert your object to iterable array using Object.keys, Object.values or Object.entries (ES7).



回答2:

If you dont want to use generator syntax, you can use another way define iterator function.

    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}`);
    }


回答3:

Plain objects (options in this case) are not iterable in ES6. You need to either define an iterator for your object or do something like:

for(let k of Object.keys(options)) {
  console.log(`Property ${k}, ${options[k]}`);
};