diff options
Diffstat (limited to 'files/uk/web/javascript/reference/global_objects/array/map')
-rw-r--r-- | files/uk/web/javascript/reference/global_objects/array/map/index.html | 349 |
1 files changed, 349 insertions, 0 deletions
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 +--- +<div>{{JSRef}}</div> + +<p>Метод <code><strong>map()</strong></code> <strong>створює новий масив</strong> з результатами виклику наданої функції на кожному елементі масиву, який викликав метод.</p> + +<p>{{EmbedInteractiveExample("pages/js/array-map.html")}}</p> + +<div class="hidden"> +<p>The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request." </p> +</div> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="brush: js"><var>var new_array = arr.map(function callback(currentValue[, index[, array]]) { + // Повернути елемент нового масиву new_array +}[, thisArg])</var></pre> + +<h3 id="Параметри">Параметри</h3> + +<dl> + <dt><code>callback</code></dt> + <dd>Функція, яка повертає елемент нового масиву. Приймає три аргументи:</dd> + <dd> + <dl> + <dt><code>currentValue</code></dt> + <dd>Поточний елемент масиву.</dd> + <dt><code>index</code>{{optional_inline}}</dt> + <dd>Індекс поточного елементу масиву</dd> + <dt><code>array</code>{{optional_inline}}</dt> + <dd>Сам масив, на якому був викликаний <code>map</code>.</dd> + </dl> + </dd> + <dt><code>thisArg</code>{{optional_inline}}</dt> + <dd>Значення, що буде використане як <code>this</code> при виконанні <code>callback</code>.</dd> +</dl> + +<h3 id="Значення_що_повертається_(return_value)">Значення, що повертається (return value)</h3> + +<p>Новий масив, кожен елемент якого є результатом функції <code>callback</code>.</p> + +<h2 id="Опис">Опис</h2> + +<p>Метод <code>map</code> викликає передану <code>callback-функцію</code> <strong>один раз для кожного елементу</strong> масиву, в заданому порядку, та створює новий масив з результатів. <code>callback</code> викликаться тільки для індексів яким відповідають значення, включно з <a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/undefined">undefined</a>. Функція не викликається для елеметів значення яких відсутні (мається на увазі, індекси які не були явно задані, які були видалені або яким не було присвоєне значення).</p> + +<p>Остільки <code>map</code> створює новий масив, викликати його, якщо ви не збираєтесь використовувати повернений масив, є антишаблоном; скористайтесь натомість <a href="https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach"><code>forEach</code></a> або <a href="https://developer.mozilla.org/uk/docs/Web/JavaScript/Reference/Statements/for...of"><code>for-of</code></a>. Ознаки того, що вам не підходить метод <code>map</code>: А) Ви не використовуєте масив, який він повертає, і/або Б) Ви не повертаєте значення у функції <code>callback</code>.</p> + +<p><code>callback</code> викликається з трьома аргументами: значення елемента, індекс елемента, та масив на якому операцію було викликано.</p> + +<p>Якщо <code>thisArg</code> параметр переданий в <code>map</code>, він буде використовуватись як ключове слово this для <code>callback-функції</code>. В іншому випадку, значення {{jsxref("undefined")}} буде використане як <code>this</code>. Значення this, яке спостерігається в callback-функції, в кінцевому рахунку визначається згідно <a href="/uk/docs/Web/JavaScript/Reference/Operators/this">звичайних правил для визначення this, видимого з функції</a>.</p> + +<p><code>map</code> не змінює масив, на якому був викликаний (хоча <code>callback</code>, якщо був викликаний, може змінити).</p> + +<p>Діапазон елементів, які обробляє метод map, визначений до того як callback-функція буде визвана вперше. Елементи які будуть додані до масиву після виклику map, не будуть оброблені callback-функцією. Якщо існуючі в масиві елементи змінені або видалені, їхні значення при потраплянні в callback-функцію, будуть такими якими вони є на той час коли map обробляє їх. Елементи які були видалені до і після того як map був визваний, ігноруються. </p> + +<p>Згідно з алгоритмом, визначеним у специфікації, якщо масив на якому було викликано map, розріджений, то масив на виході теж буде розрідженим, залишаючи ті ж самі індекси пустими.</p> + +<h2 id="Приклади">Приклади</h2> + +<h3 id="Перетворення_масиву_з_числами_в_масив_квадратних_коренів">Перетворення масиву з числами в масив квадратних коренів</h3> + +<p>Наступний код бере масив з числами і створює новий масив, який складається з квадратних коренів чисел з першого масиву.</p> + +<pre class="brush: js">var numbers = [1, 4, 9]; +var roots = numbers.map(function(num) { +return Math.sqrt(num) +}); +// roots тепер [1, 2, 3] +// numbers залишається [1, 4, 9] +</pre> + +<h3 id="Використання_map_для_переформатування_об'єктів_в_масиві">Використання map для переформатування об'єктів в масиві</h3> + +<p>Наступний код використовує масив з об'єктами щоб створити новий масив з переформатованими об'єктами.</p> + +<pre class="brush: js">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}] +</pre> + +<h3 id="Перетворення_масиву_чисел_використовуючи_функцію_з_аргументом">Перетворення масиву чисел використовуючи функцію з аргументом</h3> + +<p>Наступний код показує як map працює коли функція що потребує один аргумент, використовує його. Аргумент буде автоматично присвоєний з кожного елементу масиву коли map буде проходитись по оригінальному масиву..</p> + +<pre class="brush: js">var numbers = [1, 4, 9]; +var doubles = numbers.map(function(num) { + return num * 2; +}); + +// doubles тепер [2, 8, 18] +// numbers залишається [1, 4, 9] +</pre> + +<h3 id="Загальне_використання_map">Загальне використання <code>map</code></h3> + +<p>Цей приклад показує як використовувати map на рядках ({{jsxref("String")}}) щоб отримати масив байтів в ASCII кодуванні яке відображає значення літер:</p> + +<pre class="brush: js">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] +</pre> + +<h3 id="Загальне_використання_map_з_querySelectorAll">Загальне використання <code>map</code> з <code>querySelectorAll</code></h3> + +<p>Даний приклад показує, як виконати перебір набору об'єктів, отриманих методом <code>querySelectorAll</code>. Тому що метод <code>querySelectorAll</code> повертає <strong><em>NodeList</em></strong>, який є колекцією об'єктів.</p> + +<p>У даному випадку ми повертаємо значення всіх вибраних опцій на екрані:</p> + +<pre class="brush: js">var elems = document.querySelectorAll('select option:checked'); +var values = Array.prototype.map.call(elems, function(obj) { + return obj.value; +}); +</pre> + +<p>Це простіше зробити методом {{jsxref("Array.from()")}}.</p> + +<h3 id="Хитрий_спосіб_використання">Хитрий спосіб використання</h3> + +<p>(<a href="http://www.wirfs-brock.com/allen/posts/166">натхненний цим блог-постом</a>)</p> + +<p>Загальноприйнято використовувати функцію callback з одним аргументом (елемент по якому проходиться функція). Деякі функції також використовуються з одним аргументом, хоча можуть приймати і більше додаткових аргументів, що не є обов'язковими. Це може призводити до неочікуваної поведінки.</p> + +<p>Розглянемо:</p> + +<pre class="brush: js">["1", "2", "3"].map(parseInt);</pre> + +<p>Хоча можна було б очікувати <code>[1, 2, 3]</code>, справжнім результатом буде <code>[1, NaN, NaN]</code>.</p> + +<p>Метод <code>parseInt</code> часто використовується з одним аргументом, але приймає два. Перший - це вираз, а другий - основа системи числення для функції зворотного виклику. <code>Array.prototype.map</code> передає 3 аргументи:</p> + +<ul> + <li>елемент</li> + <li>індекс</li> + <li>масив</li> +</ul> + +<p>Третій аргумент ігнорується методом parseInt, <u>але не другий</u>, звідси й можлива плутанина. Ось стислий огляд кроків перебору:</p> + +<pre class="brush: js">// 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</pre> + +<p>Поговоримо про рішення.</p> + +<pre class="brush: js">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]</pre> + +<p>Ще один варіант результату метода map, що викликається з parseInt в якості параметра, виглядає наступним чином:</p> + +<pre class="brush: js">var xs = ['10', '10', '10']; + +xs = xs.map(parseInt); + +console.log(xs); +// Результат 10,NaN,2 може бути неочікуваним, з огляду вищеописане.</pre> + +<h3 id="Масив_містить_значення_undefined">Масив містить значення undefined</h3> + +<p>Коли повертається undefined або нічого не повертається:</p> + +<pre class="brush: js">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]</pre> + +<h2 id="Поліфіл">Поліфіл</h2> + +<p><font face="Consolas, Liberation Mono, Courier, monospace">Метод <code>map</code> </font>був доданий до ECMA-262 стандарту в 5-тій редакції; тому він може бути присутнім не у всіх реалізаціях стандарту. Ви можете обійти це, вставляючи наступний код на початок вашого скритпу, дозволяючи використовувати map в реалізаціях які ще його не підтримують. Цей алгоритм є точно таким який вказаний в ECMA-262, 5му виданні, передбачаючи що {{jsxref("Object")}}, {{jsxref("TypeError")}}, і {{jsxref("Array")}} мають свої власні значення і що <code>callback.call</code> обчислює початкове значення <code>{{jsxref("Function.prototype.call")}}</code>.</p> + +<pre class="brush: js">// Функціональні кроки 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; + }; +} +</pre> + +<h2 id="Специфікації">Специфікації</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Специфікація</th> + <th scope="col">Статус</th> + <th scope="col">Коментар</th> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.4.4.19', 'Array.prototype.map')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> + <p>Початкове визначення. Реалізоване в JavaScript 1.6.</p> + </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-array.prototype.map', 'Array.prototype.map')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-array.prototype.map', 'Array.prototype.map')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Сумісність_з_веб-переглядачами">Сумісність з веб-переглядачами</h2> + +<div class="hidden"> +<p>The compatibility table in this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> +</div> + +<p>{{Compat("javascript.builtins.Array.map")}}</p> + +<h2 id="Дивіться_також">Дивіться також</h2> + +<ul> + <li>{{jsxref("Array.prototype.forEach()")}}</li> + <li>Об'єкт {{jsxref("Map")}}</li> + <li>{{jsxref("Array.from()")}}</li> +</ul> |