Apply your JS skills to key Mozilla projects as an MDN Fellow! http://mzl.la/MDNFellowship

mozilla
您的搜索结果

    Array.prototype.map()

    这篇文章需要编辑方面的审查。

    概述

    map() 方法返回一个由原数组中的每个元素调用一个指定方法后的返回值组成的新数组。

    语法

    array.map(callback[, thisArg])

    参数

    callback
    原数组中的元素经过该方法后返回一个新的元素。
    currentValue
    callback 的第一个参数,数组中当前被传递的元素。
    index
    callback 的第二个参数,数组中当前被传递的元素的索引。
    array
    callback 的第三个参数,调用 map 方法的数组。
    thisArg
    执行 callback 函数时 this 指向的对象。

    描述

    map 方法会给原数组中的每个元素都按顺序调用一次 callback 函数。callback 每次执行后的返回值组合起来形成一个新数组。 callback 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用 delete 删除的索引则不会被调用。

    callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。

    如果 thisArg 参数有值,则每次 callback 函数被调用的时候,this 都会指向 thisArg 参数上的这个对象。如果省略了 thisArg 参数,或者赋值为 nullundefined,则 this 指向全局对象 。

    map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。

    当一个数组运行 map 方法时,数组的长度在调用第一次 callback 方法之前就已经确定。在 map 方法整个运行过程中,不管 callback 函数中的操作给原数组是添加还是删除了元素。map 方法都不会知道,如果数组元素增加,则新增加的元素不会被 map 遍历到,如果数组元素减少,则 map 方法还会认为原数组的长度没变,从而导致数组访问越界。如果数组中的元素被改变或删除,则他们被传入 callback 的值是 map 方法遍历到他们那一刻时的值。

    示例

    例子:将数组中的单词转换成对应的复数形式.

    下面的代码将一个数组中的所有单词转换成对应的复数形式.

    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;
    
        // 4.如果callback不是函数,则抛出TypeError异常.
        if ({}.toString.call(callback) != "[object Function]") {
          throw new TypeError(callback + " is not a function");
        }
    
        // 5. 如果参数thisArg有值,则将T赋值为thisArg;否则T为undefined.
        if (thisArg) {
          T = thisArg;
        }
    
        // 6. 创建新数组A,长度为原数组O长度len
        A = new Array(len);
    
        // 7. 将k赋值为0
        k = 0;
    
        // 8. 当 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++;
        }
    
        // 9. 返回新数组A
        return A;
      };      
    }

    规范

    Specification Status Comment
    ECMAScript 5.1 (ECMA-262)
    Array.prototype.map
    Standard Initial definition.
    Implemented in JavaScript 1.6
    ECMAScript 6 (ECMA-262)
    Array.prototype.map
    Draft  

    浏览器兼容性

    Feature Firefox (Gecko) Chrome Internet Explorer Opera Safari
    Basic support (Yes) (Yes) 9 (Yes) (Yes)
    Feature Firefox Mobile (Gecko) Android IE Mobile Opera Mobile Safari Mobile
    Basic support ? ? ? ? ?

    基于 Kangax's compat tables

    相关链接

    文档标签和贡献者

    此页面的贡献者有: ziyunfei, AlexChao, xiaomingming, teoli
    最后编辑者: xiaomingming,