JS的map方法
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
參數,
或者賦值為 null
或 undefined
,則 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方法