Array.from()

La méthode Array.from() permet de créer une nouvelle instance d'Array à partir d'un objet itérable ou semblable à un tableau.

Array.from("toto");
// ["t", "o", "t", "o"]

Syntaxe

Array.from(arrayLike[, fonctionMap[, thisArg]])

Paramètres

arrayLike
Un objet semblable à un tableau ou bien un objet itérable dont on souhaite créer un tableau, instance d'Array.
fonctionMap
Argument optionnel, une fonction à appliquer à chacun des éléments du tableau.
thisArg
Argument optionnel. La valeur à utiliser pour this lors de l'exécution de la fonction fonctionMap.

Valeur de retour

Une nouvelle instance de Array.

Description

Array.from permet de créer des instances d'Array à partir :

  • d'objets semblables à des tableaux (qui disposent d'une propriété length et d'éléments indexés) ou
  • d'objets itérables (des objets dont on peut avoir les éléments comme Map et Set).

Array.from possède un paramètre optionnel fonctionMap, qui permet d'exécuter une fonction map sur chacun des éléments du tableau (ou de l'instance de la classe fille) qui est créé. Autrement dit Array.from(obj, mapFn, thisArg) correspond exactement à Array.from(obj).map(mapFn, thisArg), sauf qu'il n'y a pas de tableau intermédiaire de créé. Cet aspect est notamment important pour certaines classes filles, comme les tableaux typés (en effet, un tableau intermédiaire aurait eu ses valeurs tronquées pour qu'elles soient du type approprié).

La propriété length de la méthode from est 1.

Avec ES6, la syntaxe de classe permet d'avoir des sous-classes pour les objets natifs comme pour les objets définis par l'utilisateur. Ainsi, les méthodes statiques de classe comme Array.from sont héritées par les sous-classes d'Array et créent de nouvelles instances de la sous-classe d'Array.

Exemples

// créer une instance d'Array à partir de l'objet arguments qui est semblable à un tableau
function f() {
  return Array.from(arguments);
}

f(1, 2, 3); 
// [1, 2, 3]


// Ça fonctionne avec tous les objets itérables...
// Set
var s = new Set(["toto", window]);
Array.from(s);   
// ["toto", window]


// Map
var m = new Map([[1, 2], [2, 4], [4, 8]]);
Array.from(m);                          
// [[1, 2], [2, 4], [4, 8]]  


// String
Array.from("toto");                      
// ["t", "o", "t", "o"]


// En utilisant une fonction fléchée pour remplacer map
// et manipuler des éléments
Array.from([1, 2, 3], x => x + x);      
// [2, 4, 6]


// Pour générer une séquence de nombres
Array.from({length: 5}, (v, k) => k);    
// [0, 1, 2, 3, 4]

Prothèse d'émulation (polyfill)

Array.from fut ajouté avec la sixième édition du standard ECMA-262. Il se peut donc que cette méthode ne soit pas supportée par les différentes implémentations du standard. Le code qui suit peut être intégré afin d'émuler cette méthode dans les environnements où elle est absente. Cet algorithme est précisément celui défini par ECMAScript 6 (si on a bien Object et TypeError avec leurs valeurs originelles et callback.call qui correspond bien à la valeur originale de Function.prototype.call). Étant donné que les itérables ne peuvent pas être émulés, cette implémentation ne supporte pas les itérables génériques définis avec la sixième édition d'ECMA-262.

// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Référence : https://people.mozilla.org/~jorendorff/es6-draft.html#sec-array.from
if (!Array.from) {
  Array.from = (function () {
    var toStr = Object.prototype.toString;
    var isCallable = function (fn) { 
      return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
    };
    var toInteger = function (value) { 
      var number = Number(value); 
      if (isNaN(number)) { return 0; }
      if (number === 0 || !isFinite(number)) { return number; }
      return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number)); 
    };
    var maxSafeInteger = Math.pow(2, 53) - 1;
    var toLength = function (value) { 
      var len = toInteger(value);
      return Math.min(Math.max(len, 0), maxSafeInteger);
    }; 
  
    // La propriété length de la méthode vaut 1.
    return function from(arrayLike/*, mapFn, thisArg */) { 
      // 1. Soit C, la valeur this
      var C = this;
      
      // 2. Soit items le ToObject(arrayLike).
      var items = Object(arrayLike); 
      
      // 3. ReturnIfAbrupt(items).
      if (arrayLike == null) { 
        throw new TypeError("Array.from doit utiliser un objet semblable à un tableau - null ou undefined ne peuvent pas être utilisés");
      }
    
      // 4. Si mapfn est undefined, le mapping sera false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {  
        // 5. sinon      
        // 5. a. si IsCallable(mapfn) est false, on lève une TypeError.
        if (!isCallable(mapFn)) { 
          throw new TypeError('Array.from: lorsqu il est utilisé le deuxième argument doit être une fonction'); 
        }
     
        // 5. b. si thisArg a été fourni, T sera thisArg ; sinon T sera undefined.
        if (arguments.length > 2) { 
          T = arguments[2];
        }
      }
    
      // 10. Soit lenValue pour Get(items, "length").
      // 11. Soit len pour ToLength(lenValue).
      var len = toLength(items.length);  
     
      // 13. Si IsConstructor(C) vaut true, alors
      // 13. a. Soit A le résultat de l'appel à la méthode interne [[Construct]] avec une liste en argument qui contient l'élément len.
      // 14. a. Sinon, soit A le résultat de ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);
   
      // 16. Soit k égal à 0.
      var k = 0;  // 17. On répète tant que k < len… 
      var kValue;
      while (k < len) {
        kValue = items[k]; 
        if (mapFn) {
          A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k); 
        } else {
          A[k] = kValue;
        }
        k += 1;
      }
      // 18. Soit putStatus égal à Put(A, "length", len, true).
      A.length = len;  // 20. On renvoie A.
      return A;
    };
  }());
}

Spécification

Spécification État Commentaires
ECMAScript 2015 (6th Edition, ECMA-262)
La définition de 'Array.from' dans cette spécification.
Standard Définition initiale.
ECMAScript 2017 Draft (ECMA-262)
La définition de 'Array.from' dans cette spécification.
Projet  

Compatibilité des navigateurs

Fonctionnalité Chrome Firefox (Gecko) Internet Explorer Edge Opera Safari
Support simple 45 32 (32) Pas de support (Oui) (Oui) 9.0
Fonctionnalité Android Chrome pour Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Support simple Pas de support Pas de support 32.0 (32) Pas de support Pas de support Pas de support

Voir aussi

Étiquettes et contributeurs liés au document

 Contributeurs à cette page : SphinxKnight, Acen1991
 Dernière mise à jour par : SphinxKnight,