Array.from()

Traducción en curso

El método Array.from() crea una nueva instancia de Array a partir de un objeto iterable.

En EcmaScript6, la sintaxis de clase permite a la subclases y a las clases las definidas por el usuario incorporarse; como resultado, los métodos estáticos de la Class-side tales como Array.from son heredados por las subclases de Array y crean nuevas instancias de la subclase, no de Array.

Sintaxis

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

Parámetros

arrayLike
Objeto iterable para convertirlo en vector.
mapFn
Opcional. Función de mapa para llamar a cada  elementos del vector.
thisArg
Opcional. Valor a usar cuando se ejecute mapFn.

Descripción

Array.from() permite crear Arrays de:

  • Objetos array-like (objetos con propiedad length o elementos indexados).
  • Objetos iterables (Objetos de los cuales se pueden obtener sus elementos como Map y Set).

Array.from() tiene un parámetro opcional mapFn, que te permite ejecutar una función map  a cada elemento del array (o a la subclase del objeto) que se ha creado. Para aclararlo, Array.from(obj, mapFn, thisArg) es igual que Array.from(obj).map(mapFn, thisArg), excepto en que éste no crea un array intermedio. Esto es importante para ciertas subclases de array, vectores tipados, ya que el vector intermedio necesitaría tener valores truncados para trabajar con el tipo adecuado.

La propiedad length del método from() es 1.

Ejemplos

// Objeto array-like (arguments) a Array
function f() {
  return Array.from(arguments);
}

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


// Algunos objetos iterables...
// Set
var s = new Set(["foo", window]);
Array.from(s);   
// ["foo", window]


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


// String
Array.from("foo");                      
// ["f", "o", "o"]


// Usando una función de flecha como función
// para manipular los elementos
Array.from([1, 2, 3], x => x + x);      
// [2, 4, 6]


// Generar secuencia de números
Array.from({length: 5}, (v, k) => k);    
// [0, 1, 2, 3, 4]

Polyfill

Array.from fue añadido en el estándar ECMA-262 en la 6ta edición; así que no puede estar presente en otras implementaciones del estándar. Puedes usarlo insertando este código al comienzo de sus scripts, permitiendo el uso de Array.from en implementaciones que no lo soportan. Este algoritmo es el mismo especificado en ECMA-262, 6ta edición, suponiendo que Object y TypeError tengan sus valores originales y callback.call evalúa el valor original de Function.prototype.call. Adicionalmente, ya que verdaderos iterables pueden no ser polyficados, esta implementación no soporta iterables genéricos como definidos en la 6ta edición de ECMA-262.

// Production steps of ECMA-262, Edition 6, 22.1.2.1
// Reference: 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 propiedad length del método from es 1.
    return function from(arrayLike/*, mapFn, thisArg */) {
      // 1. Let C be the this value.
      var C = this;

      // 2. Let items be ToObject(arrayLike).
      var items = Object(arrayLike);

      // 3. Return IfAbrupt(items).
      if (arrayLike == null) {
        throw new TypeError("Array.from requiere un objeto array-like - not null or undefined");
      }

      // 4. Si mapfn no está definida, entonces deja que sea false.
      var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
      var T;
      if (typeof mapFn !== 'undefined') {
        // 5. else      
        // 5. a If IsCallable(mapfn) es false, lanza una excepción TypeError.
        if (!isCallable(mapFn)) {
          throw new TypeError('Array.from: si hay mapFn, el segundo argumento debe ser una función');
        }

        // 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
        if (arguments.length > 2) {
          T = arguments[2];
        }
      }

      // 10. Let lenValue be Get(items, "length").
      // 11. Let len be ToLength(lenValue).
      var len = toLength(items.length);

      // 13. If IsConstructor(C) is true, then
      // 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
      // 14. a. Else, Let A be ArrayCreate(len).
      var A = isCallable(C) ? Object(new C(len)) : new Array(len);

      // 16. Let k be 0.
      var k = 0;
      // 17. Repeat, while k < len… (also steps a - h)
      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. Let putStatus be Put(A, "length", len, true).
      A.length = len;
      // 20. Return A.
      return A;
    };
  }());
}

Especificaciones

Especificación Estado Comentario
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.from' in that specification.
Standard Definición inicial
ECMAScript 2017 Draft (ECMA-262)
The definition of 'Array.from' in that specification.
Draft  

Compatibilidad con navegadores

Característica Chrome Firefox (Gecko) Edge Internet Explorer Opera Safari
Soporte básico 45 32 (32) (Yes) No support No support 9.0
Característica Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Soporte básico No support No support 32.0 (32) No support No support No support

Ver también

Etiquetas y colaboradores del documento

 Colaboradores en esta página: joakku, thzunder
 Última actualización por: joakku,