Array.from()

Статичний метод Array.from() (із) створює новий, поверхнево скопійований примірник Array на основі ітерованого або масивоподібного об'єкта.

Спробуйте його в дії

Синтаксис

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

Параметри

arrayLike (масивоподібне)

Ітерований чи масивоподібний об'єкт для перетворення на масив.

mapFn (функція відображення) Необов'язкове

Функція до виклику на кожному елементі масиву. Якщо вона задана, то кожне значення перед додаванням до масиву спершу пропускається крізь цю функцію, і замість нього до масиву додається значення, що повернено з mapFn. Ця функція викликається з наступними аргументами:

element

Поточний елемент масиву, що обробляється.

index

Індекс поточного елемента масиву, що обробляється.

thisArg Необов'язкове

Значення для використання як this при виконанні mapFn.

Повернене значення

Новий примірник Array.

Опис

Array.from() дає змогу створювати Array на основі:

  • ітерованих об'єктів (таких, як Map і Set); або, якщо об'єкт не є ітерованим,
  • масивоподібних об'єктів (об'єктів зі властивістю length та індексованими елементами).

Щоб перетворити звичайний об'єкт, що не є ітерованим або масивоподібним, на масив (шляхом перелічування його ключів властивостей, значень, або і ключів, і значень), використовуйте Object.keys(), Object.values() або Object.entries(). Щоб перетворити асинхронний ітерований об'єкт на масив, використовуйте Array.fromAsync().

Array.from() ніколи не породжує розріджених масивів. Якщо об'єкт arrayLike не має частини властивостей-індексів, то такі пропущені індекси отримують undefined у новому масиві.

Array.from() має необов'язковий параметр mapFn, котрий дає змогу виконувати функцію на кожному елементі масиву, що створюється, подібно до map(). Ясніше висловлюючись, Array.from(obj, mapFn, thisArg) дає такий само результат, як Array.from(obj).map(mapFn, thisArg), окрім того, що не створює проміжний масив, і mapFn отримує лише два аргументи (element, index), без передачі всього масиву, тому що масив іще в процесі створення.

[!NOTE] Така логіка – більш важлива для типізованих масивів, адже проміжний масив обов'язково містив би значення, що вписувались би у відповідний тип. 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", пор. Python, Clojure тощо)
const range = (start, stop, step) =>
  Array.from(
    { length: Math.ceil((stop - start) / step) },
    (_, i) => start + i * step,
  );

// Згенерувати послідовність чисел від 0 (включно) до 5 (не включно) з інкрементом на 1
range(0, 4, 1);
// [0, 1, 2, 3, 4]

// Згенерувати послідовність чисел від 1 (включно) до 10 (не включно) з інкрементом на 2
range(1, 10, 2);
// [1, 3, 5, 7, 9]

// Згенерувати латинський алфавіт, користуючись тим, що він має послідовний порядок
range("A".charCodeAt(0), "Z".charCodeAt(0) + 1, 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
Chrome Edge Firefox Internet Explorer Opera Safari WebView Android Chrome Android Firefox for Android Opera Android Safari on iOS Samsung Internet Deno Node.js
from
Chrome Full support 45
Edge Full support 12
Firefox Full support 32
Internet Explorer No support Ні
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

Дивіться також