From 218934fa2ed1c702a6d3923d2aa2cc6b43c48684 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:43:23 -0500 Subject: initial commit --- .../reference/global_objects/array/map/index.html | 349 +++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 files/uk/web/javascript/reference/global_objects/array/map/index.html (limited to 'files/uk/web/javascript/reference/global_objects/array/map/index.html') diff --git a/files/uk/web/javascript/reference/global_objects/array/map/index.html b/files/uk/web/javascript/reference/global_objects/array/map/index.html new file mode 100644 index 0000000000..2c71a1fe6f --- /dev/null +++ b/files/uk/web/javascript/reference/global_objects/array/map/index.html @@ -0,0 +1,349 @@ +--- +title: Array.prototype.map() +slug: Web/JavaScript/Reference/Global_Objects/Array/map +tags: + - Array + - ECMAScript5 + - JavaScript + - Масив + - метод + - поліфіл + - прототип +translation_of: Web/JavaScript/Reference/Global_Objects/Array/map +--- +
{{JSRef}}
+ +

Метод map() створює новий масив з результатами виклику наданої функції на кожному елементі масиву, який викликав метод.

+ +

{{EmbedInteractiveExample("pages/js/array-map.html")}}

+ + + +

Синтаксис

+ +
var new_array = arr.map(function callback(currentValue[, index[, array]]) {
+    // Повернути елемент нового масиву new_array
+}[, thisArg])
+ +

Параметри

+ +
+
callback
+
Функція, яка повертає елемент нового масиву. Приймає три аргументи:
+
+
+
currentValue
+
Поточний елемент масиву.
+
index{{optional_inline}}
+
Індекс поточного елементу масиву
+
array{{optional_inline}}
+
Сам масив, на якому був викликаний map.
+
+
+
thisArg{{optional_inline}}
+
Значення, що буде використане як this при виконанні callback.
+
+ +

Значення, що повертається (return value)

+ +

Новий масив, кожен елемент якого є результатом функції callback.

+ +

Опис

+ +

Метод map викликає передану callback-функцію один раз для кожного елементу масиву, в заданому порядку, та створює новий масив з результатів. callback викликаться тільки для індексів яким відповідають значення, включно з undefined. Функція не викликається для елеметів значення яких відсутні (мається на увазі, індекси які не були явно задані, які були видалені або яким не було присвоєне значення).

+ +

Остільки map створює новий масив, викликати його, якщо ви не збираєтесь використовувати повернений масив, є антишаблоном; скористайтесь натомість forEach або for-of. Ознаки того, що вам не підходить метод map: А) Ви не використовуєте масив, який він повертає, і/або Б) Ви не повертаєте значення у функції callback.

+ +

callback викликається з трьома аргументами: значення елемента, індекс елемента, та масив на якому операцію було викликано.

+ +

Якщо thisArg параметр переданий в map, він буде використовуватись як ключове слово this  для callback-функції. В іншому випадку, значення {{jsxref("undefined")}} буде використане як this. Значення this, яке спостерігається в callback-функції, в кінцевому рахунку визначається згідно звичайних правил для визначення this, видимого з функції.

+ +

map не змінює масив, на якому був викликаний (хоча callback, якщо був викликаний, може змінити).

+ +

Діапазон елементів, які обробляє метод map, визначений до того як callback-функція буде визвана вперше. Елементи які будуть додані до масиву після виклику map, не будуть оброблені callback-функцією. Якщо існуючі в масиві елементи змінені або видалені, їхні значення при потраплянні в callback-функцію, будуть такими якими вони є на той час коли map обробляє їх. Елементи які були видалені до і після того як map був визваний, ігноруються. 

+ +

Згідно з алгоритмом, визначеним у специфікації, якщо масив на якому було викликано map, розріджений, то масив на виході теж буде розрідженим, залишаючи ті ж самі індекси пустими.

+ +

Приклади

+ +

Перетворення масиву з числами в масив квадратних коренів

+ +

Наступний код бере масив з числами і створює новий масив, який складається з квадратних коренів чисел з першого масиву.

+ +
var numbers = [1, 4, 9];
+var roots = numbers.map(function(num) {
+return Math.sqrt(num)
+});
+// roots тепер [1, 2, 3]
+// numbers залишається [1, 4, 9]
+
+ +

Використання map для переформатування об'єктів в масиві

+ +

Наступний код використовує масив з об'єктами щоб створити новий масив з переформатованими об'єктами.

+ +
var kvArray = [{key:1, value:10},
+               {key:2, value:20},
+               {key:3, value: 30}];
+
+var reformattedArray = kvArray.map(obj =>{
+   var rObj = {};
+   rObj[obj.key] = obj.value;
+   return rObj;
+});
+// reformattedArray тепер [{1:10}, {2:20}, {3:30}],
+
+// kvArray залишається:
+// [{key:1, value:10},
+//  {key:2, value:20},
+//  {key:3, value: 30}]
+
+ +

Перетворення масиву чисел використовуючи функцію з аргументом

+ +

Наступний код показує як map працює коли функція що потребує один аргумент, використовує його.  Аргумент буде автоматично присвоєний з кожного елементу масиву коли map буде проходитись по оригінальному масиву..

+ +
var numbers = [1, 4, 9];
+var doubles = numbers.map(function(num) {
+  return num * 2;
+});
+
+// doubles тепер [2, 8, 18]
+// numbers залишається [1, 4, 9]
+
+ +

Загальне використання map

+ +

Цей приклад показує як використовувати map на рядках ({{jsxref("String")}}) щоб отримати масив байтів в ASCII кодуванні яке відображає значення літер:

+ +
var map = Array.prototype.map;
+var a = map.call('Hello World', function(x) {
+   return x.charCodeAt(0);
+});
+// a тепер дорівнює [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
+
+ +

Загальне використання map з querySelectorAll

+ +

Даний приклад показує, як виконати перебір набору об'єктів, отриманих методом querySelectorAll. Тому що метод querySelectorAll повертає NodeList, який є колекцією об'єктів.

+ +

У даному випадку ми повертаємо значення всіх вибраних опцій на екрані:

+ +
var elems = document.querySelectorAll('select option:checked');
+var values = Array.prototype.map.call(elems, function(obj) {
+  return obj.value;
+});
+
+ +

Це простіше зробити методом {{jsxref("Array.from()")}}.

+ +

Хитрий спосіб використання

+ +

(натхненний цим блог-постом)

+ +

Загальноприйнято використовувати функцію callback з одним аргументом (елемент по якому проходиться функція). Деякі функції також використовуються з одним аргументом, хоча можуть приймати і більше додаткових аргументів, що не є обов'язковими. Це може призводити до неочікуваної поведінки.

+ +

Розглянемо:

+ +
["1", "2", "3"].map(parseInt);
+ +

Хоча можна було б очікувати [1, 2, 3], справжнім результатом буде [1, NaN, NaN].

+ +

Метод parseInt часто використовується з одним аргументом, але приймає два. Перший - це вираз, а другий - основа системи числення для функції зворотного виклику. Array.prototype.map передає 3 аргументи:

+ + + +

Третій аргумент ігнорується методом parseInt, але не другий, звідси й можлива плутанина. Ось стислий огляд кроків перебору:

+ +
// parseInt(string, radix) -> map(parseInt(value, index))
+/*  first iteration (index is 0): */ parseInt("1", 0); // 1
+/* second iteration (index is 1): */ parseInt("2", 1); // NaN
+/*  third iteration (index is 2): */ parseInt("3", 2); // NaN
+ +

Поговоримо про рішення.

+ +
function returnInt(element) {
+  return parseInt(element, 10);
+}
+
+['1', '2', '3'].map(returnInt); // [1, 2, 3]
+// Результатом є масив чисел (як і очікувалось)
+
+// Те саме, але з використанням лаконічного стрілкового синтаксису
+['1', '2', '3'].map( str => parseInt(str) );
+
+// Простіший спосіб досягти вищевказаного
+['1', '2', '3'].map(Number); // [1, 2, 3]
+
+// На відміну від parseInt(), Number() також поверне десятковий або експоненціальний запис:
+['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
+// Для порівняння, якщо використати parseInt() для попереднього масиву:
+['1.1', '2.2e2', '3e300'].map( str => parseInt(str) ); // [1, 2, 3]
+ +

Ще один варіант результату метода map, що викликається з parseInt в якості параметра, виглядає наступним чином:

+ +
var xs = ['10', '10', '10'];
+
+xs = xs.map(parseInt);
+
+console.log(xs);
+// Результат 10,NaN,2 може бути неочікуваним, з огляду вищеописане.
+ +

Масив містить значення undefined

+ +

Коли повертається undefined або нічого не повертається:

+ +
var numbers = [1, 2, 3, 4];
+var filteredNumbers = numbers.map(function(num, index) {
+  if(index < 2) {
+     return num;
+  }
+});
+// filteredNumbers дорівнює [1, 2, undefined, undefined]
+// numbers досі дорівнює [1, 2, 3, 4]
+ +

Поліфіл

+ +

Метод map був доданий до ECMA-262 стандарту в 5-тій редакції; тому він може бути присутнім не у всіх реалізаціях стандарту. Ви можете обійти це, вставляючи наступний код на початок вашого скритпу, дозволяючи використовувати map в реалізаціях які ще його не підтримують. Цей алгоритм є точно таким який вказаний в  ECMA-262, 5му виданні, передбачаючи що {{jsxref("Object")}}, {{jsxref("TypeError")}}, і {{jsxref("Array")}} мають свої власні значення  і що callback.call обчислює початкове значення {{jsxref("Function.prototype.call")}}.

+ +
// Функціональні кроки ECMA-262, версія 5, 15.4.4.19
+// Довідка: http://es5.github.io/#x15.4.4.19
+if (!Array.prototype.map) {
+
+  Array.prototype.map = function(callback, thisArg) {
+
+    var T, A, k;
+
+    if (this == null) {
+      throw new TypeError(' this is null or not defined');
+    }
+
+    // 1. Нехай O дорівнює результату виклику ToObject з |this|
+    //    в якості аргументу.
+    var O = Object(this);
+
+    // 2. Нехай lenValue дорівнює результату виклику внутрішнього методу O
+    //    Get з аргументом "length".
+    // 3. Нехай len дорівнює ToUint32(lenValue).
+    var len = O.length >>> 0;
+
+    // 4. Якщо IsCallable(callback) дорівнює false, викинути виняток TypeError.
+    // Див.: http://es5.github.com/#x9.11
+    if (typeof callback !== 'function') {
+      throw new TypeError(callback + ' is not a function');
+    }
+
+    // 5. Якщо надано thisArg, нехай T дорівнює thisArg; інакше нехай T дорівнює undefined.
+    if (arguments.length > 1) {
+      T = thisArg;
+    }
+
+    // 6. Нехай A дорівнює новому масиву, створеному виразом new Array(len),
+    //    де Array - це стандартний вбудований конструктор з таким ім'ям,
+    //    а len дорівнює значенню len.
+    A = new Array(len);
+
+    // 7. Нехай k дорівнює 0
+    k = 0;
+
+    // 8. Повторювати, доки k < len
+    while (k < len) {
+
+      var kValue, mappedValue;
+
+      // а. Нехай Pk дорівнює ToString(k).
+      //   Цей метод неявно застосовується до лівого операнда оператора in
+      // б. Нехай kPresent дорівнює результату виклику внутрішнього методу O
+      //    HasProperty з аргументом Pk.
+      //   Цей крок можна об'єднати з в
+      // в. Якщо kPresent дорівнює true, тоді
+      if (k in O) {
+
+        // і. Нехай kValue дорівнює результату виклику внутрішнього методу O
+        //    Get з аргументом Pk.
+        kValue = O[k];
+
+        // ii. Нехай mappedValue дорівнює результату виклику внутрішнього
+        //     методу callback Call з T у якості значення this та списком
+        //     аргументів, що містить kValue, k та O.
+        mappedValue = callback.call(T, kValue, k, O);
+
+        // iii. Викликати внутрішній метод A DefineOwnProperty з аргументами
+        // Pk, Property Descriptor
+        // { Value: mappedValue,
+        //   Writable: true,
+        //   Enumerable: true,
+        //   Configurable: true },
+        // та false.
+
+        // У переглядачах, що підтримують Object.defineProperty, використовуйте:
+        // Object.defineProperty(A, k, {
+        //   value: mappedValue,
+        //   writable: true,
+        //   enumerable: true,
+        //   configurable: true
+        // });
+
+        // Для найкращої підтримки переглядачів, використовуйте:
+        A[k] = mappedValue;
+      }
+      // г. Збільшити k на 1.
+      k++;
+    }
+
+    // 9. повернути A
+    return A;
+  };
+}
+
+ +

Специфікації

+ + + + + + + + + + + + + + + + + + + + + + + + +
СпецифікаціяСтатусКоментар
{{SpecName('ES5.1', '#sec-15.4.4.19', 'Array.prototype.map')}}{{Spec2('ES5.1')}} +

Початкове визначення. Реалізоване в JavaScript 1.6.

+
{{SpecName('ES6', '#sec-array.prototype.map', 'Array.prototype.map')}}{{Spec2('ES6')}}
{{SpecName('ESDraft', '#sec-array.prototype.map', 'Array.prototype.map')}}{{Spec2('ESDraft')}}
+ +

Сумісність з веб-переглядачами

+ + + +

{{Compat("javascript.builtins.Array.map")}}

+ +

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

+ + -- cgit v1.2.3-54-g00ecf