1. 程式人生 > >ES5 陣列方法之-----map

ES5 陣列方法之-----map

ES5 陣列方法map

概述

map() 方法返回一個由原陣列中的每個元素呼叫一個指定方法後的返回值組成的新陣列。

語法

array.map(callback[, thisArg])

引數

callback

原陣列中的元素經過該方法後返回一個新的元素。

currentValue

callback 的第一個引數,陣列中當前被傳遞的元素。

index

callback 的第二個引數,陣列中當前被傳遞的元素的索引。

array

callback 的第三個引數,呼叫 map 方法的陣列。

thisArg

執行 callback 函式時 this 指向的物件。

例子:將陣列中的單詞轉換成對應的複數形式.

下面的程式碼將一個數組中的所有單詞轉換成對應的複數形式.

 

function fuzzyPlural(single) {
  var result = single.replace(/o/g, 'e');  
  if( single === 'kangaroo'){
    result += 'se';
  }
  return result; 
}

var words = ["foot", "goose", "moose", "kangaroo"];
console.log(words.map(fuzzyPlural));

// ["feet", "geese", "meese", "kangareese"]

例子:求陣列中每個元素的平方根

下面的程式碼建立了一個新陣列,值為原陣列中對應數字的平方根。

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

例子:在字串上使用 map 方法

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

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 方法中的 callback 函式只需要接受一個引數,就是正在被遍歷的陣列元素本身。但這並不意味著 map 只給 callback 傳了一個引數。這個思維慣性可能會讓我們犯一個很容易犯的錯誤。

 

// 下面的語句返回什麼呢:
["1", "2", "3"].map(parseInt);
// 你可能覺的會是[1, 2, 3]
// 但實際的結果是 [1, NaN, NaN]

// 通常使用parseInt時,只需要傳遞一個引數.但實際上,parseInt可以有兩個引數.第二個引數是進位制數.可以通過語句"alert(parseInt.length)===2"來驗證.
// map方法在呼叫callback函式時,會給它傳遞三個引數:當前正在遍歷的元素, 元素索引, 原陣列本身.
// 第三個引數parseInt會忽視, 但第二個引數不會,也就是說,parseInt把傳過來的索引值當成進位制數來使用.從而返回了NaN.

/*
//應該使用如下的使用者函式returnInt

function returnInt(element){
  return parseInt(element,10);
}

["1", "2", "3"].map(returnInt);
// 返回[1,2,3]
*/

相容舊環境(Polyfill)

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

 

// 實現 ECMA-262, Edition 5, 15.4.4.19
// 參考: http://es5.github.com/#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. 將O賦值為呼叫map方法的陣列.
    var O = Object(this);

    // 2.將len賦值為陣列O的長度.
    var len = O.length >>> 0;

    // 3.如果callback不是函式,則丟擲TypeError異常.
    if (Object.prototype.toString.call(callback) != "[object Function]") {
      throw new TypeError(callback + " is not a function");
    }

    // 4. 如果引數thisArg有值,則將T賦值為thisArg;否則T為undefined.
    if (thisArg) {
      T = thisArg;
    }

    // 5. 建立新陣列A,長度為原陣列O長度len
    A = new Array(len);

    // 6. 將k賦值為0
    k = 0;

    // 7. 當 k < len 時,執行迴圈.
    while(k < len) {

      var kValue, mappedValue;

      //遍歷O,k為原陣列索引
      if (k in O) {

        //kValue為索引k對應的值.
        kValue = O[ k ];

        // 執行callback,this指向T,引數有三個.分別是kValue:值,k:索引,O:原陣列.
        mappedValue = callback.call(T, kValue, k, O);

        // 返回值新增到新陣列A中.
        A[ k ] = mappedValue;
      }
      // k自增1
      k++;
    }

    // 8. 返回新陣列A
    return A;
  };      
}