Monthly Archives: avril 2015

Iterator et iterable en javascript

Les concepts de d’itérator et d’itérable font leur entrée avec l’arrivée de ES6.

Iterator

Un iterator est un objet possédant une méthode next() et renvoyant quand elle est appelée une structure contenant les propriétés done et value

Exemple d’iterator

function myArrayIterator(arr) {
  var index = 0;
  return {
    next : function {
      if (index < arr.length) {
        return { done: false, value: arr[index++] };
      } else {
        return { done: true };
      }
    }
  }
}
var it = myArrayIterator(['s1', 's2']);
console.log(it.next()); // { done: false, value: "s1" }
console.log(it.next()); // { done: false, value: "s2" }
console.log(it.next()); // { done: true }

Cet iterator n’est pas iterable, c’est à dire qu’il ne peut pas être parcouru par une boucle for ..of

var it2 = myArrayIterator(['s1', 's2'])
for(var item of it2) { // TypeError: it2[Symbol.iterator] is not a function
  console.log(item);
}

Iterable

Afin d’être itérable, un objet doit implémenter la méthode @@iterator, cela signifie que l’objet (ou un des objets de sa chaîne de prototypes) doit avoir une propriété avec une clé Symbol.iterator. Cette méthode doit renvoyer un object iterator.

Rendons notre objet myArrayIterator iterable :

function myArrayIteratorIterable(arr) {
  var index = 0;
  return {
    [Symbol.iterator] : function () {
      return  {
        next : function () {
          if (index < arr.length) {
            return { done: false, value: arr[index++] };
          } else {
            return { done: true };
          }
        }
      }
    }
  }
}

var it2 = myArrayIteratorIterable(tab)
for(var item of it2) {
  console.log(item);
}
// s1
// s2

Exemple d’objet iterable

var batman = new (function() {
  var self = this;
  var index=0;
  
  
  this.nom = 'Wayne';  
  this.prenom = 'Bruce';
  this.parler = function() {
    console.log('Bonjour');
  }
  
  this[Symbol.iterator] = function () {
    var keys = Object.keys(self);
    return { 
      next : function() {
        if (index < keys.length) {
          return { done: false, value: self[keys[index++]] };
        } else {
          return { done: true };
        }
      }
    }
  };

})();

for(var item of obj) {
  console.log(i);
}

// "Wayne"
// "Bruce"
// function obj</this.parler()