Переклад не закінчено. Будь ласка, допоможіть перекласти цю статтю з англійської.

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

var numbers = [1, 5, 10, 15];
var roots = numbers.map(function(x) {
   return x * 2;
});
// roots зараз [2, 10, 20, 30]
// numbers залишається [1, 5, 10, 15]

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// roots зараз [1, 2, 3]
// numbers залишається [1, 4, 9]

Синтаксис

arr.map(callback[, thisArg])

Параметри

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

Зворотнє значення (return value)

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

Опис

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

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

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

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

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

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

Приклади

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

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

var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt);
// 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(function(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 на рядках (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. У даному випадку ми отримуємо всі вибрані опції на екрані та виведені у консолі:

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

Використання map для перевертання рядка

var str = '12345';
Array.prototype.map.call(str, function(x) {
  return x;
}).reverse().join(''); 

// Результат: '54321'
// Додатково: використай '===' щоб перевірити чи оригінальний рядок є паліндромом

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

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

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

// Розглянемо:
['1', '2', '3'].map(parseInt);
// Ми очікуємо [1, 2, 3]
// А результатом є [1, NaN, NaN]

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

function returnInt(element) {
  return parseInt(element, 10);
}

['1', '2', '3'].map(returnInt); // [1, 2, 3]
// Результатом є масив чисел (як і очікувалось)

// Простіший спосіб досягти вищевказаного
['1', '2', '3'].map(Number); // [1, 2, 3]

Поліфіл

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

// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: 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. Let O be the result of calling ToObject passing the |this| 
    //    value as the argument.
    var O = Object(this);

    // 2. Let lenValue be the result of calling the Get internal 
    //    method of O with the argument "length".
    // 3. Let len be ToUint32(lenValue).
    var len = O.length >>> 0;

    // 4. If IsCallable(callback) is false, throw a TypeError exception.
    // See: http://es5.github.com/#x9.11
    if (typeof callback !== 'function') {
      throw new TypeError(callback + ' is not a function');
    }

    // 5. If thisArg was supplied, let T be thisArg; else let T be undefined.
    if (arguments.length > 1) {
      T = thisArg;
    }

    // 6. Let A be a new array created as if by the expression new Array(len) 
    //    where Array is the standard built-in constructor with that name and 
    //    len is the value of len.
    A = new Array(len);

    // 7. Let k be 0
    k = 0;

    // 8. Repeat, while k < len
    while (k < len) {

      var kValue, mappedValue;

      // a. Let Pk be ToString(k).
      //   This is implicit for LHS operands of the in operator
      // b. Let kPresent be the result of calling the HasProperty internal 
      //    method of O with argument Pk.
      //   This step can be combined with c
      // c. If kPresent is true, then
      if (k in O) {

        // i. Let kValue be the result of calling the Get internal 
        //    method of O with argument Pk.
        kValue = O[k];

        // ii. Let mappedValue be the result of calling the Call internal 
        //     method of callback with T as the this value and argument 
        //     list containing kValue, k, and O.
        mappedValue = callback.call(T, kValue, k, O);

        // iii. Call the DefineOwnProperty internal method of A with arguments
        // Pk, Property Descriptor
        // { Value: mappedValue,
        //   Writable: true,
        //   Enumerable: true,
        //   Configurable: true },
        // and false.

        // In browsers that support Object.defineProperty, use the following:
        // Object.defineProperty(A, k, {
        //   value: mappedValue,
        //   writable: true,
        //   enumerable: true,
        //   configurable: true
        // });

        // For best browser support, use the following:
        A[k] = mappedValue;
      }
      // d. Increase k by 1.
      k++;
    }

    // 9. return A
    return A;
  };
}

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

Специфікація Статус Коментар
ECMAScript 5.1 (ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Standard

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

ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Standard  
ECMAScript Latest Draft (ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Living Standard  

Браузерна сумісність

Особливість

Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базова підтримка (Yes) 1.5 (1.8) 9 (Yes) (Yes)
Особливість Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базова підтримка (Yes) (Yes) 1.0 (1.8) (Yes) (Yes) (Yes)

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

Мітки документа й учасники

 Зробили внесок у цю сторінку: no-riders, artemyavorskyi, AlinaDigtyar, piton13, probil, trofima, Kiwka
 Востаннє оновлена: no-riders,