Array.from()
Статичний метод Array.from()
(із) створює новий, поверхнево скопійований примірник Array
на основі ітерованого чи масивоподібного об'єкта.
Спробуйте його в дії
Синтаксис
Array.from(arrayLike)
// Стрілкова функція
Array.from(arrayLike, (element) => { /* … */ } )
Array.from(arrayLike, (element, index) => { /* … */ } )
// Функція відображення
Array.from(arrayLike, mapFn)
Array.from(arrayLike, mapFn, thisArg)
// Функція відображення, оголошена на місці
Array.from(arrayLike, function mapFn(element) { /* … */ })
Array.from(arrayLike, function mapFn(element, index) { /* … */ })
Array.from(arrayLike, function mapFn(element) { /* … */ }, thisArg)
Array.from(arrayLike, function mapFn(element, index) { /* … */ }, thisArg)
Параметри
arrayLike
(масивоподібне)Ітерований чи масивоподібний об'єкт для перетворення на масив.
mapFn
(функція відображення) Необов'язковеФункція відображення, що буде викликана на кожному елементі масиву. Якщо вона задана, то кожне значення, додане до масиву, спершу буде пропущено крізь цю функцію, і замість нього до масиву буде додано результівне значення
mapFn
.Ця функція викликається з наступними аргументами:
element
Поточний елемент масиву, що обробляється.
index
Індекс поточного елемента масиву, що обробляється.
thisArg
Необов'язковеЗначення для використання як
this
при виконанніmapFn
.
Повернене значення
Новий примірник Array
.
Опис
Array.from()
дає змогу створювати Array
на основі:
- ітерованих об'єктів (таких, як
Map
іSet
); або, якщо об'єкт не є ітерованим, - масивоподібних об'єктів (об'єктів зі властивістю
length
та індексованими елементами).
Array.from()
ніколи не породжує розріджених масивів. Якщо об'єкт arrayLike
не має частини властивостей-індексів, то такі пропущені індекси отримують undefined
у новому масиві.
Array.from()
має необов'язковий параметр mapFn
, котрий дає змогу виконувати функцію на кожному елементі масиву, що створюється, подібно до map()
. Ясніше висловлюючись, Array.from(obj, mapFn, thisArg)
дає такий само результат, як Array.from(obj).map(mapFn, thisArg)
, окрім того, що не створює проміжний масив, і mapFn
отримує лише два аргументи (element
, index
), без передачі всього масиву, тому що масив іще в процесі створення.
Примітка: Така логіка – більш важлива для типізованих масивів, адже проміжний масив обов'язково містив би значення, що вписувались би у відповідний тип.
Array.from()
реалізований так, щоб мати таку ж сигнатуру, якTypedArray.from()
.
Метод Array.from()
є узагальненим фабричним методом. Наприклад, якщо підклас Array
успадковує метод from()
, то успадкований метод from()
повертатиме нові примірники підкласу, а не примірники Array
. Фактично значення this
може бути будь-якою функцією-конструктором, котра приймає єдиний аргумент, що представляє довжину нового масиву. Коли передається arrayLike
– ітерований об'єкт, то конструктор викликається без аргументів; коли передається масивоподібний об'єкт, то конструктор викликається з нормалізованою довжиною масивоподібного об'єкта. Остаточне значення length
присвоюється знову, коли ітерація завершується. Якщо значення this
не є функцією-конструктором, то замість нього використовується конструктор Array
.
Приклади
Array на основі String
Array.from("foo");
// [ "f", "o", "o" ]
Array на основі Set
const set = new Set(["foo", "bar", "baz", "foo"]);
Array.from(set);
// [ "foo", "bar", "baz" ]
Array на основі Map
const map = new Map([
[1, 2],
[2, 4],
[4, 8],
]);
Array.from(map);
// [[1, 2], [2, 4], [4, 8]]
const mapper = new Map([
["1", "a"],
["2", "b"],
]);
Array.from(mapper.values());
// ['a', 'b'];
Array.from(mapper.keys());
// ['1', '2'];
Array на основі NodeList
// Створити масив, заснований на властивості елементів DOM
const images = document.querySelectorAll("img");
const sources = Array.from(images, (image) => image.src);
const insecureSources = sources.filter((link) => link.startsWith("http://"));
Array на основі масивоподібного об'єкта (arguments)
function f() {
return Array.from(arguments);
}
f(1, 2, 3);
// [ 1, 2, 3 ]
Застосування стрілкових функцій та Array.from()
// Застосування стрілкової функції як функції відображення для
// роботи з елементами
Array.from([1, 2, 3], (x) => x + x);
// [2, 4, 6]
// Згенерувати послідовність чисел
// Оскільки масив ініціалізується з `undefined` на кожній позиції,
// значення `v` нижче буде `undefined`
Array.from({ length: 5 }, (v, i) => i);
// [0, 1, 2, 3, 4]
Генератор послідовності (діапазон)
// Функція – генератор послідовності (загальноприйнято зветься "діапазоном" – "range", наприклад, у Clojure, PHP тощо)
const range = (start, stop, step) =>
Array.from({ length: (stop - start) / step + 1 }, (_, i) => start + i * step);
// Згенерувати діапазон чисел 0..4
range(0, 4, 1);
// [0, 1, 2, 3, 4]
// Згенерувати діапазон чисел 1..10 з кроком 2
range(1, 10, 2);
// [1, 3, 5, 7, 9]
// Згенерувати за допомогою Array.from алфавіт, користуючись тим, що він має послідовний порядок
range("A".charCodeAt(0), "Z".charCodeAt(0), 1).map((x) =>
String.fromCharCode(x)
);
// ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
Виклик from() на конструкторах-немасивах
Метод from()
може бути викликаний на будь-якій функції-конструкторі, що приймає єдиний аргумент, котрий представляє довжину нового масиву.
function NotArray(len) {
console.log("NotArray викликано з довжиною", len);
}
// Ітерований об'єкт
console.log(Array.from.call(NotArray, new Set(["foo", "bar", "baz"])));
// NotArray викликано з довжиною undefined
// NotArray { '0': 'foo', '1': 'bar', '2': 'baz', length: 3 }
// Масивоподібний об'єкт
console.log(Array.from.call(NotArray, { length: 1, 0: "foo" }));
// NotArray викликано з довжиною 1
// NotArray { '0': 'foo', length: 1 }
Коли значення this
не є конструктором, повертається звичайний об'єкт Array
.
console.log(Array.from.call({}, { length: 1, 0: "foo" })); // [ 'foo' ]
Специфікації
Сумісність із браузерами
desktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
from
|
Chrome Full support 45 | Edge Full support 12 | Firefox Full support 32 | Internet Explorer No support No | Opera Full support 32 | Safari Full support 9 | WebView Android Full support 45 | Chrome Android Full support 45 | Firefox for Android Full support 32 | Opera Android Full support 32 | Safari on iOS Full support 9 | Samsung Internet Full support 5.0 | Deno Full support 1.0 | Node.js Full support 4.0.0 |