--- title: Array.prototype.map() slug: Web/JavaScript/Reference/Global_Objects/Array/map tags: - Array - ECMAScript5 - JavaScript - JavaScript 1.6 - Method - Prototype - Reference - Référence(2) - polyfill translation_of: Web/JavaScript/Reference/Global_Objects/Array/map ---
Метод map()
создаёт новый массив с результатом вызова указанной функции для каждого элемента массива.
let new_array = arr.map(function callback( currentValue[, index[, array]]) { // Возвращает элемент для new_array }[, thisArg])
callback
Функция, вызываемая для каждого элемента массива arr
. Каждый раз, когда callback
выполняется, возвращаемое значение добавляется в new_array
.
Функция callback
, создающая элемент в новом массиве, принимает три аргумента:
currentValue
index
{{optional_inline}}array
{{optional_inline}}thisArg
{{optional_inline}}this
при вызове функции callback
Новый массив, где каждый элемент является результатом callback
функции.
Метод map
вызывает переданную функцию callback
один раз для каждого элемента, в порядке их появления и конструирует новый массив из результатов её вызова. Функция callback
вызывается только для индексов массива, имеющих присвоенные значения, включая {{jsxref("Global_Objects/undefined", "undefined")}}. Она не вызывается для пропущенных элементов массива (то есть для индексов, которые никогда не были заданы, которые были удалены или которым никогда не было присвоено значение.
Функция callback
вызывается с тремя аргументами: значением элемента, индексом элемента и массивом, по которому осуществляется проход.
Если в метод map
был передан параметр thisArg
, при вызове callback
он будет использоваться в качестве значения this
. В противном случае в качестве значения this
будет использоваться значение {{jsxref("Global_Objects/undefined", "undefined")}}. В конечном итоге, значение this
, наблюдаемое из функции callback
, определяется согласно обычным правилам определения this
, видимого из функции.
Метод map
не изменяет массив, для которого он был вызван (хотя функция callback
может это делать).
Диапазон элементов, обрабатываемых методом map
, устанавливается до первого вызова функции callback
. Элементы, добавленные в массив после начала выполнения метода map
, не будут посещены функцией callback
. Если существующие элементы массива изменяются функцией callback
, их значения, переданные в функцию, будут значениями на тот момент времени, когда метод map
посетит их; удалённые элементы посещены не будут.
Следующий код берёт массив чисел и создаёт новый массив, содержащий квадратные корни чисел из первого массива.
var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); // теперь roots равен [1, 2, 3], а numbers всё ещё равен [1, 4, 9]
Следующий код показывает, как работает отображение, когда функция требует один аргумент. Аргумент будет автоматически присваиваться каждому элементу массива, когда 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("Global_Objects/String", "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 = [].map.call(elems, function(obj) { return obj.value; });
Более простым способом будет использование метода {{jsxref("Array.from()")}}.
map
для переворачивания строкиvar str = '12345'; [].map.call(str, function(x) { return x; }).reverse().join(''); // Вывод: '54321' // Бонус: используйте '===' для проверки того, является ли строка палиндромом
Более простым способом будет использование метода {{jsxref("String.split()")}} (см. пример обращение строки при помощи метода split()).
(навеяно этой записью в блоге)
Распространённой практикой является использование колбэк-функции с одним аргументом (элемент, над которым производится операция). Некоторые функции также широко используется с одним аргументом, хотя они принимают дополнительные необязательные аргументы. Эти привычки могут привести к неожиданному поведению программы.
// Рассмотрим пример: ['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'].map(Number); // [1, 2, 3]
Метод map
был добавлен к стандарту ECMA-262 в 5-м издании; поэтому он может отсутствовать в других реализациях стандарта. Вы можете работать с ним, добавив следующий код в начало ваших скриптов, он позволяет использовать map
в реализациях, которые не поддерживают этот метод. Этот алгоритм является точно тем, что описан в ECMA-262 5-го издания; он предполагает, что {{jsxref("Global_Objects/Object", "Object")}}, {{jsxref("Global_Objects/TypeError", "TypeError")}} и {{jsxref("Global_Objects/Array", "Array")}} имеют свои первоначальные значения и что callback.call
вычисляется в оригинальное значение {{jsxref("Function.prototype.call")}}.
// Шаги алгоритма ECMA-262, 5-е издание, 15.4.4.19 // Ссылка (en): http://es5.github.com/#x15.4.4.19 // Ссылка (ru): http://es5.javascript.ru/x15.4.html#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 равным результату вызова внутреннего метода Get // объекта O с аргументом "length". // 3. Положим len равным ToUint32(lenValue). var len = O.length >>> 0; // 4. Если вызов IsCallable(callback) равен false, выкидываем исключение TypeError. // Смотрите (en): http://es5.github.com/#x9.11 // Смотрите (ru): http://es5.javascript.ru/x9.html#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; // a. Положим Pk равным ToString(k). // Это неявное преобразование для левостороннего операнда в операторе in // b. Положим kPresent равным результату вызова внутреннего метода HasProperty // объекта O с аргументом Pk. // Этот шаг может быть объединён с шагом c // c. Если kPresent равен true, то if (k in O) { // i. Положим kValue равным результату вызова внутреннего метода Get // объекта O с аргументом Pk. kValue = O[k]; // ii. Положим mappedValue равным результату вызова внутреннего метода Call // функции callback со значением T в качестве значения this и списком // аргументов, содержащим kValue, k и O. mappedValue = callback.call(T, kValue, k, O); // iii. Вызовем внутренний метод DefineOwnProperty объекта A с аргументами // Pk, Описатель Свойства // { 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; } // d. Увеличим 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')}} |
{{Compat("javascript.builtins.Array.map")}}