We're looking for a user researcher to understand the needs of developers and designers. Is this you or someone you know? Check out the post: https://mzl.la/2IGzdXS

翻譯不完整。請協助 翻譯此英文文件

map() 方法會建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。


var new_array = arr.map(function callback(currentValue[, index[, array]]) {
    // Return element for new_array
}[, thisArg])


呼叫 map 方法的陣列。
選擇性的參數。執行 callback 回呼函式的 this 值。




map 會將所有陣列中的元素依序分別傳入一次callback 函式當中,並以此回呼函式每一次被呼叫的回傳值來建構一個新的陣列。callback 函式只會於陣列目前迭代之索引有指派值時(包含 undefined)被調用,而在該陣列索引沒有元素時(即未被設定的索引:已被刪除或從未被賦值)並不會呼叫回呼函式。

callback 函式於被調用時會傳入三個參數:元素值、元素之索引、以及被迭代的陣列物件。

若有提供 thisArg 參數予 map 方法,thisArg 將會被當作回呼函式的 this 值,否則 this 會是 undefinedcallback 的最終 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]

Using map generically querySelectorAll

This example shows how to iterate through a collection of objects collected by querySelectorAll. In this case we get all selected options on the screen and printed on the console:

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

Easier way would be using Array.from() method.

Tricky use case

(inspired by this blog post)

It is common to use the callback with one argument (the element being traversed). Certain functions are also commonly used with one argument, even though they take additional optional arguments. These habits may lead to confusing behaviors.

// Consider:
['1', '2', '3'].map(parseInt);
// While one could expect [1, 2, 3]
// The actual result is [1, NaN, NaN]

// parseInt is often used with one argument, but takes two.
// The first is an expression and the second is the radix.
// To the callback function, Array.prototype.map passes 3 arguments: 
// the element, the index, the array
// The third argument is ignored by parseInt, but not the second one,
// hence the possible confusion. See the blog post for more details

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]


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,
// 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.

    // 9. return A
    return A;


Specification Status Comment
ECMAScript 5.1 (ECMA-262)
The definition of 'Array.prototype.map' in that specification.
Standard Initial definition. Implemented in JavaScript 1.6.
ECMAScript 2015 (6th Edition, ECMA-262)
The definition of 'Array.prototype.map' in that specification.
ECMAScript Latest Draft (ECMA-262)
The definition of 'Array.prototype.map' in that specification.


FeatureChromeEdgeFirefoxInternet ExplorerOperaSafari
Basic support Yes Yes1.59 Yes Yes
FeatureAndroid webviewChrome for AndroidEdge mobileFirefox for AndroidOpera AndroidiOS SafariSamsung Internet
Basic support Yes Yes Yes4 Yes Yes Yes



此頁面的貢獻者: jackblackevo, jWorker, akari0624
最近更新: jackblackevo,