1. 程式人生 > >JS的map方法

JS的map方法

world 除了 循環 動態對象 lin follow fine 反轉字符串 tro

map() 方法創建一個新數組,其結果是該數組中的每個元素都調用一個提供的函數後返回的結果。

let numbers = [1, 5, 10, 15];
let doubles = numbers.map((x) => {
   return x * 2;
});

// doubles is now [2, 10, 20, 30]
// numbers is still [1, 5, 10, 15]


let numbers = [1, 4, 9];
let roots = numbers.map(Math.sqrt);

// roots is now [1, 2, 3]
// numbers is still [1, 4, 9]

語法Edit

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

參數Edit

callback
生成新數組元素的函數,使用三個參數:
currentValue
callback 的第一個參數,數組中正在處理的當前元素。
index
callback 的第二個參數,數組中正在處理的當前元素的索引。
array
callback 的第三個參數,map 方法被調用的數組。
thisArg
可選的。執行 callback
函數時 使用的this 值。

返回值

一個新數組,每個元素都是回調函數的結果。

描述Edit

map 方法會給原數組中的每個元素都按順序調用一次 callback 函數。callback 每次執行後的返回值(包括 undefined)組合起來形成一個新數組。 callback 函數只會在有值的索引上被調用;那些從來沒被賦過值或者使用 delete 刪除的索引則不會被調用。

callback 函數會被自動傳入三個參數:數組元素,元素索引,原數組本身。

如果 thisArg 參數有值,則每次 callback 函數被調用的時候,this 都會指向 thisArg參數上的這個對象。如果省略了 thisArg

參數,或者賦值為 nullundefined,則 this 指向全局對象 。

map 不修改調用它的原數組本身(當然可以在 callback 執行時改變原數組)。

使用 map 方法處理數組時,數組元素的範圍是在 callback 方法第一次調用之前就已經確定了。在 map 方法執行的過程中:原數組中新增加的元素將不會被 callback 訪問到;若已經存在的元素被改變或刪除了,則它們的傳遞到 callback 的值是 map 方法遍歷到它們的那一時刻的值;而被刪除的元素將不會被訪問到。

示例Edit

求數組中每個元素的平方根

下面的代碼創建了一個新數組,值為原數組中對應數字的平方根。

1 var numbers = [1, 4, 9];
2 var roots = numbers.map(Math.sqrt);
3 // roots的值為[1, 2, 3], numbers的值仍為[1, 4, 9]

使用 map 重新格式化數組中的對象

以下代碼將一個包含對象的數組用以創建一個包含新重新格式化對象的新數組。

 1 var kvArray = [{key: 1, value: 10}, 
 2                {key: 2, value: 20}, 
 3                {key: 3, value: 30}];
 4 
 5 var reformattedArray = kvArray.map(function(obj) { 
 6    var rObj = {};
 7    rObj[obj.key] = obj.value;
 8    return rObj;
 9 });
10 
11 // reformattedArray 數組為: [{1: 10}, {2: 20}, {3: 30}], 
12 
13 // kvArray 數組未被修改: 
14 // [{key: 1, value: 10}, 
15 //  {key: 2, value: 20}, 
16 //  {key: 3, value: 30}]

用一個僅有一個參數的函數來mapping一個數字數組

下面的代碼表示了當函數需要一個參數時map的工作方式。這個參數會遍歷原始數組中的元素。

1 var numbers = [1, 4, 9];
2 var doubles = numbers.map(function(num) {
3   return num * 2;
4 });
5 
6 // doubles數組的值為: [2, 8, 18]
7 // numbers數組未被修改: [1, 4, 9]

一般的 map 方法

下面的例子演示如何在一個 String 上使用 map 方法獲取字符串中每個字符所對應的 ASCII 碼組成的數組:

1 var map = Array.prototype.map
2 var a = map.call("Hello World", function(x) { 
3   return x.charCodeAt(0); 
4 })
5 // a的值為[72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]

querySelectorAll 應用

下面代碼展示了如何去遍歷用 querySelectorAll 得到的動態對象集合。在這裏,我們獲得了文檔裏所有選中的選項,並將其打印:

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

反轉字符串

1 var str = ‘12345‘;
2 Array.prototype.map.call(str, function(x) {
3   return x;
4 }).reverse().join(‘‘); 
5 
6 // 輸出: ‘54321‘
7 // Bonus: use ‘===‘ to test if original string was a palindrome

使用技巧案例

通常情況下,map 方法中的 callback 函數只需要接受一個參數,就是正在被遍歷的數組元素本身。但這並不意味著 map 只給 callback 傳了一個參數。這個思維慣性可能會讓我們犯一個很容易犯的錯誤。

 1 // 下面的語句返回什麽呢:
 2 ["1", "2", "3"].map(parseInt);
 3 // 你可能覺的會是[1, 2, 3]
 4 // 但實際的結果是 [1, NaN, NaN]
 5 
 6 // 通常使用parseInt時,只需要傳遞一個參數.
 7 // 但實際上,parseInt可以有兩個參數.第二個參數是進制數.
 8 // 可以通過語句"alert(parseInt.length)===2"來驗證.
 9 // map方法在調用callback函數時,會給它傳遞三個參數:當前正在遍歷的元素, 
10 // 元素索引, 原數組本身.
11 // 第三個參數parseInt會忽視, 但第二個參數不會,也就是說,
12 // parseInt把傳過來的索引值當成進制數來使用.從而返回了NaN.
13 
14 function returnInt(element) {
15   return parseInt(element, 10);
16 }
17 
18 [‘1‘, ‘2‘, ‘3‘].map(returnInt); // [1, 2, 3]
19 // 意料之中的結果
20 
21 // 也可以使用簡單的箭頭函數,結果同上
22 [‘1‘, ‘2‘, ‘3‘].map( str => parseInt(str) );
23 
24 // 一個更簡單的方式:
25 [‘1‘, ‘2‘, ‘3‘].map(Number); // [1, 2, 3]
26 // 與`parseInt` 不同,下面的結果會返回浮點數或指數:
27 [‘1.1‘, ‘2.2e2‘, ‘3e300‘].map(Number); // [1.1, 220, 3e+300]

兼容舊環境(Polyfill)Edit

map 是在最近的 ECMA-262 標準中新添加的方法;所以一些舊版本的瀏覽器可能沒有實現該方法。在那些沒有原生支持 map 方法的瀏覽器中,你可以使用下面的 Javascript 代碼來實現它。所使用的算法正是 ECMA-262,第 5 版規定的。假定Object, TypeError, 和 Array 有他們的原始值。而且 callback.call 的原始值也是 Function.prototype.call

 1 // 實現 ECMA-262, Edition 5, 15.4.4.19
 2 // 參考: http://es5.github.com/#x15.4.4.19
 3 if (!Array.prototype.map) {
 4   Array.prototype.map = function(callback, thisArg) {
 5 
 6     var T, A, k;
 7 
 8     if (this == null) {
 9       throw new TypeError(" this is null or not defined");
10     }
11 
12     // 1. 將O賦值為調用map方法的數組.
13     var O = Object(this);
14 
15     // 2.將len賦值為數組O的長度.
16     var len = O.length >>> 0;
17 
18     // 3.如果callback不是函數,則拋出TypeError異常.
19     if (Object.prototype.toString.call(callback) != "[object Function]") {
20       throw new TypeError(callback + " is not a function");
21     }
22 
23     // 4. 如果參數thisArg有值,則將T賦值為thisArg;否則T為undefined.
24     if (thisArg) {
25       T = thisArg;
26     }
27 
28     // 5. 創建新數組A,長度為原數組O長度len
29     A = new Array(len);
30 
31     // 6. 將k賦值為0
32     k = 0;
33 
34     // 7. 當 k < len 時,執行循環.
35     while(k < len) {
36 
37       var kValue, mappedValue;
38 
39       //遍歷O,k為原數組索引
40       if (k in O) {
41 
42         //kValue為索引k對應的值.
43         kValue = O[ k ];
44 
45         // 執行callback,this指向T,參數有三個.分別是kValue:值,k:索引,O:原數組.
46         mappedValue = callback.call(T, kValue, k, O);
47 
48         // 返回值添加到新數組A中.
49         A[ k ] = mappedValue;
50       }
51       // k自增1
52       k++;
53     }
54 
55     // 8. 返回新數組A
56     return A;
57   };      
58 }

也可參見:http://www.cnblogs.com/rocky-fang/p/5756733.html //有一些JS常用函數的介紹

原文地址:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/map //JS標準庫

JS的map方法