Resum
El mètode map()
crea una nova array amb els resultats de la crida a la funció proporcionada un cop per cada element.
Sintaxi
arr.map(callback[, thisArg])
Paràmetres
callback
- Funció que produeix un element de la nova array, agafant tres arguments:
-
currentValue
- El valor actual que és processat en l'array.
index
- L'índex de l'element actual que és processat en l'array.
array
- L'array sobre la qual es crida
map.
thisArg
- Opcional. Valor a usar com a
this
quan s'executa la funció.
Descripció
map
crida a la funció passada callback
un cop per cada element de l'array, en ordre, i construeix un nou array a partir dels resultats. Només s'invoca callback
per a posicions de l'array que tinguin valors assignats, incloent undefined. No es crida per a elements no trobats (és a dir, elements que no han rebut mai un valor o bé elements que s'han eliminat).
S'invoca callback
amb tres arguments: el valor de l'element, la posició de l'element a l'array, i l'array que s'està recorrent.
Si s'ha proporcionat el paràmetre thisArg
a l'hora de cridar map
, aquest es passarà a la funció callback
com a valor per a this
dins la funció. En qualsevol altre cas el valor utilitzat com a this
serà undefined
. El valor finalment observable des de callback
es determinarà d'acord a les regles usuals per a determinar el valor de this
dins una funció.
map
no canvia l'array des del que es crida (tot i que callback
, si s'invoca, pot fer-ho).
El rang d'elements processat per map
s'estableix abans de la primera invocació de callback
. Els elements que s'hagin afegit a l'array després d'haver cridat map
no seran visitats per callback
. Si es canvient els elements existents, o s'eliminen, el valor passat a callback
serà el valor que tinguessin quan es va invocar map
; els elements que s'han eliminat no es visitaran.
Exemples
Exemple: Generar un array de rels quadrades a partir d'un array de nombres
El codi següent agafa un array de nombres i crea un nou array que contindrà les rels quadrades dels nombres del primer array.
var nombres = [1, 4, 9]; var rels = nombres.map(Math.sqrt); // rels ara val [1, 2, 3], nombres encara val [1, 4, 9]
Exemple: Utilitzar map per a canviar el format dels objectes d'un array
El codi següent agafa un array d'objectes i crea un nou array que conté els nous objectes, que tenen un format diferent.
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 ara val [{1:10}, {2:20}, {3:30}], // kvArray encara val [{key:1, value:10}, {key:2, value:20}, {key:3, value: 30}]
Exemple: Assignar els nombres d'un array al resultat d'una funció que espera un argument
El codi següent mostra com funciona map
quan s'utilitza una funció que espera un argument. L'argument rebrà automàticament el valor de cada element de l'array mentre map
recorre tot l'array original.
var nombres = [1, 4, 9]; var dobles = nombres.map(function(num) { return num * 2; }); // dobles ara val [2, 8, 18]. nombres encara val [1, 4, 9]
Exemple: utilitzar map
de forma genèrica
Aquest exemple mostra com utilitzar map
en un String
per a obtindre un array de bytes que representin el valor dels caràcters codificats amb ASCII:
var map = Array.prototype.map; var a = map.call('Hello World', function(x) { return x.charCodeAt(0); }); // a ara val [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
Exemple: Utilitzar map
de forma genèrica amb querySelectorAll
Aquest exemple mostra com iterar sobre una col·lecció d'objectes obtinguts mitjançant querySelectorAll
. En aquest cas obtenim totes les opcions seleccionades de la web:
var elems = document.querySelectorAll('select option:checked'); var values = Array.prototype.map.call(elems, function(obj) { return obj.value; });
Exemple: Utilitzar map
per a invertir un string
var str = '12345'; Array.prototype.map.call(str, function(x) { return x; }).reverse().join(''); // Sortida: '54321' // Bonus: utilitzeu '===' per a comprovar si l'string original era un palindrom
Exemple: Un cas d'ús delicat
(inspirat per aquesta entrada de blog)
És comú utilitzar la funció callback amb un sol argument (l'element corresponent a la volta del bucle de l'array que s'està recorrent). Algunes funcions també solen requerir un sol argument, tot i que també poden acceptar arguements adicionals de forma opcional. Això pot produïr comportaments confussos.
// Considerem: ['1', '2', '3'].map(parseInt); // Quan hom esperaria [1, 2, 3] // El resultat real serà [1, NaN, NaN] // parseInt s'utilitza normalment amb un argument, però admet dos. // El primer és una expressió mentre que el segon és el mòdul. // Array.prototype.map passa 3 arguments a la funció callback: // l'element, la posició de l'element i l'array // parseInt ignorarà el tercer argument, però no el segon, // provocant la confussió. Vegeu l'entrada del blog per a més detalls function returnInt(element) { return parseInt(element, 10); } ['1', '2', '3'].map(returnInt); // [1, 2, 3] // Actual result is an array of numbers (as expected) // A simpler way to achieve the above, while avoiding the "gotcha": ['1', '2', '3'].map(Number); // [1, 2, 3]
Polyfill
map
va ser afegit a l'standard ECMA-262 a la cinquena edició; degut a això aquest pot no estar present en algunes implementacions de l'standard. Es pot solventar aquest problema insertant el codi següent al principi dels scripts que el requereixin, permetent que implementacions on map
no està disponible de forma nativa en puguin fer ús. Aquest algoritme és exactament l'especificat per l'ECMA-262, 5a edició, assument que Object
, TypeError
, i Array
tenen els seus valors originals i que callback.call
s'evalua al valor original de
.Function.prototype.call
// Production steps of ECMA-262, Edition 5, 15.4.4.19
// Reference: https://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. Assignem a O el resultat de cridar a ToObject passant-li el valor de |this|
// com a argument.
var O = Object(this);
// 2. lenValue és el resultat de cridar el mètode intern
// Get de O amb l'argument "length".
// 3. Assignem a len el valor d'executar ToUint32(lenValue).
var len = O.length >>> 0;
// 4. Si IsCallable(callback) és false, llencem l'excepció TypeError.
// Vegeu: https://es5.github.com/#x9.11
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
// 5. Si s'ha passat l'argument thisArg, l'assigment a T; en cas contrari T valdrà undefined.
if (arguments.length > 1) {
T = thisArg;
}
// 6. Assignem a A el nou array creat per l'expressió new Array(len)
// on Array és el constructor standard de JavaScript amb aquest nom i
// len és el valor de len.
A = new Array(len);
// 7. Assignem 0 a k
k = 0;
// 8. Repetim mentre k < len
while (k < len) {
var kValue, mappedValue;
// a. Assignem ToString(k) a Pk.
// Això és implicit per a operands al cantó esquerra de l'operador in
// b. Assignem a kPresent el resultat de cridar el mètode intern HasProperty
// de O amb l'argument Pk.
// Es pot combinar aquest pas amb c
// c. Si kPresent és true, llavors
if (k in O) {
// i. Assignem a kValue el resultat de cridar el mètode intern
// Get de O amb l'argument Pk.
kValue = O[k];
// ii. Assignem a mappedValue el resultat de cridar el mètode intern Call
// de callback amb T com a valor de this i una llista d'arguments
// que conté kValue, k, i O.
mappedValue = callback.call(T, kValue, k, O);
// iii. Cridem el mètode intern DefineOwnProperty de A amb els arguments
// Pk, Property Descriptor
// { Value: mappedValue,
// Writable: true,
// Enumerable: true,
// Configurable: true },
// i false.
// En navegadors que suportin Object.defineProperty, utilitzeu el següent:
// Object.defineProperty(A, k, {
// value: mappedValue,
// writable: true,
// enumerable: true,
// configurable: true
// });
// Per a un millor suport de navegadors, utilitzeu el següent:
A[k] = mappedValue;
}
// d. incrementem k en 1.
k++;
}
// 9. retornem A
return A;
};
}
Especificacions
Especificació | Estat | Comentaris |
---|---|---|
ECMAScript 5.1 (ECMA-262) The definition of 'Array.prototype.map' in that specification. |
Standard | Definició inicial. Implementat a JavaScript 1.6. |
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Array.prototype.map' in that specification. |
Standard |
Compatibilitat amb navegadors
Característica | Chrome | Firefox (Gecko) | Internet Explorer | Opera | Safari |
---|---|---|---|---|---|
Suport bàsic | (Yes) | 1.5 (1.8) | 9 | (Yes) | (Yes) |
Característica | Android | Chrome for Android | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile |
---|---|---|---|---|---|---|
Suport bàsic | (Yes) | (Yes) | 1.0 (1.8) | (Yes) | (Yes) | (Yes) |