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

在我们日常开发中,操作和转换数组是一件很常见的操作,下面我们来看一个实例:

复制代码代码如下:
var desColors = [],
    srcColors = [
        {r: 255, g: 255, b: 255 }, // White
        {r: 128, g: 128, b: 128 }, // Gray
        {r: 0,   g: 0,   b: 0   }  // Black
    ];

for (var i = 0, ilen = srcColors.length; i < ilen; i++) {
    var color = srcColors[i],
        format = function(color) {
            return Math.round(color / 2);
        };

desColors.push( {
        r: format(color.r),
        g: format(color.g),
        b: format(color.b)
    });
}

// Outputs:
// [
//    {r: 128, g: 128, b: 128 },
//    {r: 64,  g: 64,  b: 64  },
//    {r: 0,   g: 0,   b: 0   }
// ];
console.log(desColors);

从上例可以看出,所有的操作重复率都比较高,如何来优化呢,幸运的是Ecmascript 5给我们提供了一个map方法,我们可以利用它来优化上例:

复制代码代码如下:
var srcColors = [
        {r: 255, g: 255, b: 255 }, // White
        {r: 128, g: 128, b: 128 }, // Gray
        {r: 0,   g: 0,   b: 0   }  // Black
    ],
    desColors = srcColors.map(function(val) {
        var format = function(color) {
            return Math.round(color/2);
        };
        return {
            r: format(val.r),
            g: format(val.g),
            b: format(val.b)
        }
    });
// Outputs:
// [
//    {r: 128, g: 128, b: 128 },
//    {r: 64,  g: 64,  b: 64  },
//    {r: 0,   g: 0,   b: 0   }
// ];
console.log(desColors);

从上例看以看出,我们使用map替换掉了for循环部分,从而只需要关心每个元素自身的实现逻辑。关于map方法详情请戳这里。

1.map基本定义:
array.map(callback[, thisArg]);

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

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

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

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

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

2.map实例:

复制代码代码如下:
//实例一:字符串上调用map方法
var result = Array.prototype.map.call("Hello world", function(x, index, arr) {
    //String {0: "H", 1: "e", 2: "l", 3: "l", 4: "o", 5: " ", 6: "w", 7: "o", 8: "r", 9: "l", 10: "d", length: 11}
    console.log(arr);
    return x.charCodeAt(0);
});
//Outputs: [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100] 
console.log(result);

上例演示了在一个String上使用map方法获取字符串中每个字符所对应的 ASCII 码组成的数组。请注意看打印的console.log(arr)打印的结果。

复制代码代码如下:
//实例二:下面的操作结果是什么?
var result = ["1", "2", "3"].map(parseInt);
//Outputs: [1, NaN, NaN] 
console.log(result);

也许你会有疑问,为什么不是[1,2,3]呢?我们知道parseInt方法可接收两个参数,第一个参数为需要转换的值,第二个参数为进制数,不了解的可以戳这里。当我们使用map方法的时候,callback函数接收三个参数,而parseInt最多只能接收两个参数,以至于第三个参数被直接舍弃,与此同时,parseInt把传过来的索引值当成进制数来使用.从而返回了NaN。看下面的输出结果:

复制代码代码如下:
//Ouputs: 1
console.log(parseInt("1", 0));
//Ouputs: 1
console.log(parseInt("1", undefined));
//Ouputs: NaN
console.log(parseInt("2", 1));
//Ouputs: NaN
console.log(parseInt("3", 2));

后面两个很容易理解,但是前两个为什么返回1呢?为了解释这个问题,我们看看官方的描述:
If radix is undefined or 0 (or absent), JavaScript assumes the following:
a) If the input string begins with “0x” or “0X”, radix is 16 (hexadecimal) and the remainder of the string is parsed.
b) If the input string begins with “0″, radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifies that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
c) If the input string begins with any other value, the radix is 10 (decimal).
在第三点中当string为其他值时,进制默认为10。

那么我们如何修改才能使上例正常输出呢?看下例:

复制代码代码如下:
var result = ["1", "2", "3"].map(function(val) {
    return parseInt(val, 10);
});
//Outputs: [1, 2, 3] 
console.log(result);

3.map方法的兼容性:
map方法在IE8及以下浏览器不支持,要想兼容老版本的浏览器,可以:

a) Don't use map.b) Use something like es5-shim to make older IE's support map.c) Use the _.map method in Underscore or Lodash for an equivalent utility function.

Javascript中Array.prototype.map()详解的更多相关文章

  1. Array.prototype.map()详解

    今天在地铁上看到这样一个小例子: ["1","2","3"].map(parseInt); 相信很多人和我一样,觉得输出的结果是[1,2,3 ...

  2. JavaScript的Array.prototype.filter()详解

    摘抄与:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/filter 概述 ...

  3. javascript中=、==、===区别详解

    javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...

  4. JavaScript中return的用法详解

    JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...

  5. javascript 中合并排序算法 详解

    javascript 中合并排序算法 详解 我会通过程序的执行过程来给大家合并排序是如何排序的...  合并排序代码如下: <script type="text/javascript& ...

  6. javascript中的this作用域详解

    javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...

  7. JavaScript中this的用法详解

    JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...

  8. javascript的Array.prototype.map()和jQuery的jQuery.map()

    两个方法都可以根据现有数组创建新数组,但在使用过程中发现有些不同之处 以下面这个数据为例: var numbers = [1, 3, 4, 6, 9]; 1. 对undefined和null的处理 a ...

  9. JavaScript中Array.prototype.sort()的详解

    摘抄来源:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort sor ...

随机推荐

  1. SQL 恢复master数据库方法,没有log文件的数据库文件恢复方法

    SQL Server恢复master数据库方法 第一步:复制model.mdf.mastlog.ldf.model.mdf.modellog.ldf.msdbdata.mdf.msdblog.ldf文 ...

  2. ios Swift 特性

    特性提供了关于声明和类型的更多信息.在Swift中有两类特性,用于修饰声明的以及用于修饰类型的.例如,required特性,当应用于一个类的指定或便利初始化器声明时,表明它的每个子类都必须实现那个初始 ...

  3. 译:Spring框架参考文档之IoC容器(未完成)

    6. IoC容器 6.1 Spring IoC容器和bean介绍 这一章节介绍了Spring框架的控制反转(IoC)实现的原理.IoC也被称作依赖注入(DI).It is a process wher ...

  4. js 后台弹窗

    后台弹出操作成功,失败信息 /// <summary> /// 弹出信息,并跳转指定页面. /// </summary> public static void AlertAnd ...

  5. js画了一个椭圆

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. javascript笔记——cookie解析

    JavaScript中的另一个机制:cookie,则可以达到真正全局变量的要求. cookie是浏览器 提供的一种机制,它将document 对象的cookie属性提供给JavaScript.可以由J ...

  7. easyui知识累计.递增.

    (001) 偶然发现 easyui 1.4.4 版本以下在使用easyloader时的一个bug(声明:只有在使用easyloader加载模块时有此问题) : (只测试过1.4.2, 1.4.3, 1 ...

  8. Eclipse JavaEE设置内置浏览器和外部浏览器

    Eclipse JavaEE设置内置浏览器和外部浏览器 我们在使用Java EE版本的Eclipse开发Java Web程序时,Eclipse会有一个默认的内置浏览器查看网页的效果,如下图 但是内置浏 ...

  9. Linux学习之路一计算机是如何工作的

    初次接触MOOC课堂,里面有个很牛X的老师教Linux,恰好自己有兴趣学,顾有了此系列学习博文. 第一讲   计算机是如何工作的 学习Linux,涉及到了C语言和汇编以及操作系统的知识,顾第一讲要讲讲 ...

  10. 升级ssh编译错误

    升级ssh 编译的时候遇到PAM headers not found,然后需要安装 pam-devel-1.1.1-20.el6.x86_64,自己下载了rpm包,安装报错,然后用yum -y ins ...