Это экспериментальная технология, часть предложения Harmony (ECMAScript 6).
Поскольку спецификация этой технологии ещё не стабилизировалась, проверьте таблицу совместимости её использования в различных браузерах. Также обратите внимание, что синтаксис и поведение экспериментальной технологии могут быть изменены в будущих версиях браузеров в соответствии с изменениями в спецификации.
Сводка
Метод Array.from()
создаёт новый экземпляр Array
из массивоподобного или итерируемого объекта.
В ES6 классовый синтаксис позволяет создавать подклассы как встроенных классов, так и классов, определённых пользователем; в результате статические методы класса, вроде Array.from
«наследуются» подклассами Array
и создают новые экземпляры подкласса, а не класса Array
.
Синтаксис
Array.from(arrayLike[, mapFn[, thisArg]])
Параметры
arrayLike
- Массивоподобный или итерируемый объект, преобразуемый в массив.
mapFn
- Необязательный параметр. Отображающая функция, вызываемая для каждого элемента массива.
thisArg
- Необязательный параметр. Значение, используемое в качестве
this
при выполнении функцииmapFn
.
Описание
Array.from()
позволяет вам создавать массивы из:
- массивоподобных объектов (объектов со свойством
length
и элементами по индексным ключам) или - итерируемых объектов (объектов, из которых вы можете достать их элементы, например
Map
илиSet
).
Array.from()
имеет необязательный параметр mapFn
, который позволяет вам выполнять функцию map
для каждого элемента создаваемого массива (или его подкласса). Проще говоря, вызов Array.from(obj, mapFn, thisArg)
эквивалентен цепочке Array.from(obj).map(mapFn, thisArg)
, за исключением того, что он не создаёт промежуточного массива. Это особенно важно для некоторых подклассов массива, вроде типизированных массивов, поскольку промежуточный массив неизбежно приведёт к усечению значений, чтобы они подпали под подходящий тип.
Свойство length
метода from()
равно 1.
Примеры
// Преобразование массивоподобного объекта (arguments) в массив (Array) function f() { return Array.from(arguments); } f(1, 2, 3); // [1, 2, 3] // Любой итерируемый объект... // Множество (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'] // Использование стрелочной функции в качестве функции отображения для // манипулирования элементами Array.from([1, 2, 3], x => x + x); // [2, 4, 6] // Генерирование последовательности чисел Array.from({ length: 5 }, (v, k) => k); // [0, 1, 2, 3, 4]
Полифилл
Метод Array.from
был добавлен к стандарту ECMA-262 в 6-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать Array.from
в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 6-го издания; он предполагает, что Object
и TypeError
имеют свои первоначальные значения и что callback.call
вычисляется в оригинальное значение Function.prototype.call
. Кроме того, поскольку истинные итерируемые объекты не могут быть заменены полифиллом, эта реализация не поддерживает общие итерируемые объекты, как они определены в 6-м издании ECMA-262.
// Шаги алгоритма ECMA-262, 6-е издание, 22.1.2.1 // Ссылка: 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); }; // Свойство length метода from равно 1. return function from(arrayLike/*, mapFn, thisArg */) { // 1. Положим C равным значению this. var C = this; // 2. Положим items равным ToObject(arrayLike). var items = Object(arrayLike); // 3. ReturnIfAbrupt(items). if (arrayLike == null) { throw new TypeError('Array.from requires an array-like object - not null or undefined'); } // 4. Если mapfn равен undefined, положим mapping равным false. var mapFn = arguments[1]; if (typeof mapFn !== 'undefined') { mapFn = arguments.length > 1 ? arguments[1] : void undefined; // 5. иначе // 5. a. Если вызов IsCallable(mapfn) равен false, выкидываем исключение TypeError. if (!isCallable(mapFn)) { throw new TypeError('Array.from: when provided, the second argument must be a function'); } // 5. b. Если thisArg присутствует, положим T равным thisArg; иначе положим T равным undefined. if (arguments.length > 2) { T = arguments[2]; } } // 10. Положим lenValue равным Get(items, "length"). // 11. Положим len равным ToLength(lenValue). var len = toLength(items.length); // 13. Если IsConstructor(C) равен true, то // 13. a. Положим A равным результату вызова внутреннего метода [[Construct]] // объекта C со списком аргументов, содержащим единственный элемент len. // 14. a. Иначе, положим A равным ArrayCreate(len). var A = isCallable(C) ? Object(new C(len)) : new Array(len); // 16. Положим k равным 0. var k = 0; // 17. Пока k < len, будем повторять... (шаги с 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. Положим putStatus равным Put(A, "length", len, true). A.length = len; // 20. Вернём A. return A; }; }()); }
Спецификации
Спецификация | Статус | Комментарии |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) Определение 'Array.from' в этой спецификации. |
Стандарт | Изначальное определение. |
Совместимость с браузерами
Возможность | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Базовая поддержка | 45 | 32 (32) | Нет | Нет | 9.0 |
Возможность | Android | Chrome для Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Базовая поддержка | Нет | Нет | 32.0 (32) | Нет | Нет | Нет |