Array.prototype.map()
Baseline
Widely available
This feature is well established and works across many devices and browser versions. Itâs been available across browsers since â¨2015å¹´7æâ©.
map() æ¹æ³æå»ºç«ä¸åæ°çé£åï¼å
¶å
§å®¹çºåé£åçæ¯ä¸åå
ç´ ç¶ç±åå¼å½å¼éç®å¾æåå³ççµæä¹éåã
å試ä¸ä¸
const array1 = [1, 4, 9, 16];
// Pass a function to map
const map1 = array1.map((x) => x * 2);
console.log(map1);
// Expected output: Array [2, 8, 18, 32]
èªæ³
let new_array = arr.map(function callback( currentValue[, index[, array]]) {
// return element for new_array
}[, thisArg])
忏
callback-
å¼å«
arrææå ç´ çåå¼å½å¼ãæ°æ¸å¼æå¨æ¯æ¬¡å·è¡callbackæå å°new_arrayãcallbackå½å¼å¯å³å ¥ä»¥ä¸ä¸å忏ï¼currentValue-
åé£åç®åæè¿ä»£èçä¸çå ç´ ã
index鏿æ§-
åé£åç®åæè¿ä»£èçä¸çå ç´ ä¹ç´¢å¼ã
array鏿æ§-
å¼å«
mapæ¹æ³çé£åã
thisArg鏿æ§-
鏿æ§ç忏ãå·è¡
callbackåå¼å½å¼çthiså¼ã
åå³å¼
ä¸åææå ç´ ççºåå¼å½å¼éç®çµæçæ°é£åã
æè¿°
map æå°ææé£åä¸çå
ç´ ä¾åºåå¥å³å
¥ä¸æ¬¡è³ callback å½å¼ç¶ä¸ï¼ä¸¦ä»¥æ¤åå¼å½å¼æ¯ä¸æ¬¡è¢«å¼å«çåå³å¼ä¾å»ºæ§ä¸åæ°çé£åãcallback å½å¼åªææ¼é£åç®åè¿ä»£ä¹ç´¢å¼æææ´¾å¼æï¼å
å«undefinedï¼è¢«èª¿ç¨ï¼èå¨è©²é£åç´¢å¼æ²æå
ç´ æï¼å³æªè¢«è¨å®çç´¢å¼ï¼å·²è¢«åªé¤æå¾æªè¢«è³¦å¼ï¼ä¸¦ä¸æå¼å«åå¼å½å¼ã
å®ä¸¦ä¸è½å¼å«ä»¥ä¸å ç´ ï¼
- ä¸åå¨çç´¢å¼ã
- æ²è¢«åªé¤ã
- æ²è¢«è³¦å¼ã
ä»éº¼æåä¸è¦ç¨ map()
å çº map æå»ºç«æ°çé£åï¼å¦æå¨ä¸æ³å»ºç«æ°é£åæä½¿ç¨è©²æ¹æ³ï¼å°±æè®æå模å¼ï¼anti-patternï¼ï¼é種æ
æ³ä¸ï¼è¦ä½¿ç¨ forEach æ for-ofã
以䏿
æ³ä¸æè©²ä½¿ç¨ mapï¼
- ä¸ä½¿ç¨åå³çæ°é£åï¼
- æ/ä¸ä¸éè¦å峿°é£åã
callback å½å¼æ¼è¢«èª¿ç¨ææå³å
¥ä¸å忏ï¼å
ç´ å¼ãå
ç´ ä¹ç´¢å¼ã以å被è¿ä»£çé£åç©ä»¶ã
è¥ææä¾ thisArg åæ¸äº map æ¹æ³ï¼thisArg å°æè¢«ç¶ä½åå¼å½å¼ç this å¼ï¼å¦å this ææ¯ undefinedãcallback çæçµ this 弿¯ä¾æå½å¼ç this è¦å便±ºå®ã
map ä¸æä¿®æ¹å¼å«å®çåå§é£åï¼éç¶å¨ callback å·è¡ææå¯è½æé麼åï¼ã
ç± map æ¹æ³æåå³ä¹æ°é£åçç¯åï¼æ¼ callback å½å¼ç¬¬ä¸æ¬¡è¢«èª¿ç¨ä¹å就已ç¶è¢«è¨å®ãèå¨å¼å« map ä¹å¾æå è³åå§é£åä¸çå
ç´ ï¼å°ä¸æå³å
¥ callback ç¶ä¸ãåå¦åå§é£åä¸å
ç´ ç弿¹è®äºï¼å callback å¾å°æ¤å
ç´ çå¼å°ææ¯ map å³å
¥å
ç´ ç¶ä¸çå¼ãèå¨å¼å« map ä¹å¾ã䏿¼è¢« map å³å
¥ callback ä¹å就被åªé¤çåå§é£åå
ç´ ï¼ä¸¦ä¸æè¢« map è¿ä»£å°ã
便è¦ç¯ä¸å®ç¾©çæ¼ç®æ³ï¼è¥å¼å« map æ¹æ³çåå§é£åçºä¸ç¨çï¼sparseï¼é£åï¼ååå³çæ°é£å乿æ¯å¨å樣索å¼ä¸ç空çç¨çé£åã
ç¯ä¾
>æä¸åæ¸åé£åè½ææå°æçéæ ¹èå¾çæ¸åé£å
以ä¸çç¨å¼ç¢¼æä¸åæ¸åé£å(array of numbers) è½ææä¸å æ°ç以該æ¸åé£å裡çä¸å忏åéæ ¹èè¨ç®çæ¸åé£å.
var numbers = [1, 4, 9];
var roots = numbers.map(Math.sqrt); //mapæreturnä¸åæ°çarray
// roots ç¾å¨æ¯ [1, 2, 3]
/* numbers 鿝 [1, 4, 9]ï¼éèæäº map() 䏿å»è®åå° numbers çå¼ï¼
map å
§é¨æ¯åäº immutable çæ©å¶ï¼Array.prototype åºä¸çéäºé«éå½å¼
大å¤é½å
·æéæ¨£å½æ¸å¼ç·¨ç¨è£¡é常注éçç¹æ§ - immutableï¼ä¸æå»æ¹è®è³æ
便ºæ¬èº«åæçå¼
*/
ä½¿ç¨ 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ãéå忏æèªåå°éä¸ååºåå§é£åä¸ååå ç´ ä¾ä½¿ç¨ã
var numbers = [1, 4, 9];
var doubles = numbers.map(function (num) {
return num * 2;
});
// doubles ç¾å¨æ¯ [2, 8, 18]
// numbers ä»ç¶æ¯ [1, 4, 9]
ä½¿ç¨ map æ¼æ³åé£å
以ä¸ç¯ä¾ç¤ºç¯å¦ä½å°ä¸å String é£åè½æçº byte é£å:
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;
});
妿ç¨ä¸ Array.from() æ¹æ³çè©±ææ´ç°¡å®ã
æ£æçç¯ä¾
ï¼ééé£çµçé¨è½æ ¼åç¼ï¼
ééä¸åï¼è¢«éæ·å ç´ çï¼åæ¸å«åºå調æ¯å常è¦çç¨æ³ãæäºå½å¼ä¹å¸¸å¸¸å¨å«æå ¶ä»å¯é¸åæ¸çæ æ³ä¸ï¼ä½¿ç¨ä¸ä¸å忏ãé種è¡çºå¸¸å¸¸æçµ¦äººå¸¶ä¾å°æã
// Consider:
["1", "2", "3"].map(parseInt);
// ä»¥çºææ¯ [1, 2, 3] å
// å
¶å¯¦æ¯ [1, NaN, NaN]
// parseInt é常åªç¨ä¸ä¸å忏 argumentï¼ä½ä»å
¶å¯¦ç¨äºå
©åï¼
// 第ä¸åæ¯è¡¨éå¼ï¼ç¬¬äºå忝é²ä½æ¸ã
// å°è©²åå¼å½å¼ä¾èªª Array.prototype.map 帶äºä¸å忏ï¼
// å
ç´ ãç´¢å¼ãé£å
// 第ä¸å忏æè¢« parseInt 忽ç¥ï¼ä½å®å¯ä¸æå¿½ç¥ç¬¬äºåï¼
// å æ¤å¯è½é æå°æãå¯ä»¥å»çä¸é¢æå°çé¨è½æ ¼æç« 以ç²ç¥è©³æ
ã
function returnInt(element) {
return parseInt(element, 10);
}
["1", "2", "3"].map(returnInt); // [1, 2, 3]
// Actual result is an array of numbers (as expected)
// Same as above, but using the concise arrow function syntax
["1", "2", "3"].map((str) => parseInt(str));
// A simpler way to achieve the above, while avoiding the "gotcha":
["1", "2", "3"].map(Number); // [1, 2, 3]
// but unlike `parseInt` will also return a float or (resolved) exponential notation:
["1.1", "2.2e2", "3e300"].map(Number); // [1.1, 220, 3e+300]
Polyfill
map was added to the ECMA-262 standard in the 5th edition; as such it may not be present in all implementations of the standard. You can work around this by inserting the following code at the beginning of your scripts, allowing use of map in implementations which do not natively support it. This algorithm is exactly the one specified in ECMA-262, 5th edition, assuming Object, TypeError, and Array have their original values and that callback.call evaluates to the original value of 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 = arguments[1];
}
// 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;
};
}
è¦ç¯
| Specification |
|---|
| ECMAScript® 2026 Language Specification > # sec-array.prototype.map > |