自定义迭代器返回空数组

时间:2016-01-14 11:38:49

标签: javascript ecmascript-6

为什么结果为空?

var myDogs = function(dogs) { 
 this.dogs = dogs;
 this[Symbol.iterator] = function() {
   let i = -1;
   return {    
    next() {
     i++;
     let j = 0;
     var dog = void(0);
     for (var dog in this.dogs) {
       if (j == i) {
        dog = { dog, hungry: dogs[dog] };
        break;
       } 
       j++;
     }
     var done = !dog;
     return { value: dog, done };
    }
   };
 };
};

var dogs = new myDogs({ buddy: true, hasso: false });
var dogHungryMap = [...dogs];
> dogHungryMap = [];

似乎我没有掌握迭代器的概念,或者我犯了一个完全愚蠢的错误。预期结果为[{ dog: 'buddy', hungry: true }, { dog: 'hasso': hungry: false }]

http://www.es6fiddle.net/ije6visa/

1 个答案:

答案 0 :(得分:5)

代码中有两个错误:

  • this,在您的next函数中,是迭代器,而不是myDogs的实例。

  • dog是迭代中的关键和结果。这意味着在迭代结束时dog 从不 undefined。你应该对变量名的语义更加小心。

解决这两个问题就是这样:

var myDogs = function(dogs) {  
 this.dogs = dogs; 
 let _this = this; 
 this[Symbol.iterator] = function() { 
   let i = -1; 
   return {     
    next() { 
     i++; 
     let j = 0; 
     var dog = void(0); 
     for (var dogName in _this.dogs) { 
       if (j == i) { 
        dog = { dog:dogName, hungry: _this.dogs[dogName] }; 
        break; 
       }  
       j++; 
     } 
     var done = !dog; 
     return { value: dog, done }; 
    } 
   }; 
 }; 
};

但是有一个更简单的解决方案:

var myDogs = function(dogs) {
 this[Symbol.iterator] = function() {
   let i = -1;
   return {
    next() {
     i++;
     var dog = Object.keys(dogs)[i];
     if (!dog) return {done:true};
     return {value:{ dog, hungry:dogs[dog] }, done:false};
    }
   };
 };
};

旁注:今天没有理由使用void(0)