Javascript中Array.prototype.map()详解


Posted in Javascript onOctober 22, 2014

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

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.

以上就是对map方法的理解,希望对初学者有所帮助,文中不妥之处,还望斧正!

Javascript 相关文章推荐
学习YUI.Ext 第七天--关于View&amp;JSONView
Mar 10 Javascript
js 判断浏览器使用的语言示例代码
Mar 22 Javascript
IE下双击checkbox反应延迟问题的解决方法
Mar 27 Javascript
JS实现网页顶部向下滑出的全国城市切换导航效果
Aug 22 Javascript
JavaScript中实现Map的示例代码
Sep 09 Javascript
JavaScript实现点击按钮就复制当前网址
Dec 14 Javascript
jquery基础知识第一讲之认识jquery
Mar 17 Javascript
AngularJS使用ng-options指令实现下拉框
Aug 23 Javascript
JS实现移动端判断上拉和下滑功能
Aug 07 Javascript
vue 微信授权登录解决方案
Apr 10 Javascript
解决vue router组件状态刷新消失的问题
Aug 01 Javascript
js模拟实现烟花特效
Mar 10 Javascript
javascript数组详解
Oct 22 #Javascript
Javascript 数组排序详解
Oct 22 #Javascript
Javascript中arguments对象详解
Oct 22 #Javascript
Javascript中的默认参数详解
Oct 22 #Javascript
js style动态设置table高度
Oct 21 #Javascript
js读写json文件实例代码
Oct 21 #Javascript
一个JavaScript防止表单重复提交的实例
Oct 21 #Javascript
You might like
几款免费开源的不用数据库的php的cms
2010/12/19 PHP
php邮箱地址正则表达式验证
2015/11/13 PHP
深入研究PHP中的preg_replace和代码执行
2018/08/15 PHP
ECMAScript 基础知识
2007/06/29 Javascript
js实现页面打印功能实例代码(附去页眉页脚功能代码)
2009/12/15 Javascript
js数组转json并在后台对其解析具体实现
2013/11/20 Javascript
javascript版2048小游戏
2015/03/18 Javascript
nodejs简单实现中英文翻译
2015/05/04 NodeJs
jquery超简单实现手风琴效果的方法
2015/06/05 Javascript
BootstrapValidator超详细教程(推荐)
2016/12/07 Javascript
Jquery Easyui选项卡组件Tab使用详解(10)
2016/12/18 Javascript
jQuery插件HighCharts绘制2D柱状图、折线图和饼图的组合图效果示例【附demo源码下载】
2017/03/09 Javascript
详解如何在Vue2中实现组件props双向绑定
2017/03/29 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
JS实现点击下拉菜单把选择的内容同步到input输入框内的实例
2018/01/23 Javascript
基于Vue实现拖拽效果
2018/04/27 Javascript
layui 设置table 行的高度方法
2018/08/17 Javascript
JavaScript原型对象原理与应用分析
2018/12/27 Javascript
使用 Vue cli 3.0 构建自定义组件库的方法
2019/04/30 Javascript
vue draggable resizable gorkys与v-chart使用与总结
2019/09/05 Javascript
如何解决vue在ios微信&quot;复制链接&quot;功能问题
2020/03/26 Javascript
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
好用的Python编辑器WingIDE的使用经验总结
2016/08/31 Python
python入门之井字棋小游戏
2020/03/05 Python
详解PyQt5中textBrowser显示print语句输出的简单方法
2020/08/07 Python
Python使用requests模块爬取百度翻译
2020/08/25 Python
用python对excel进行操作(读,写,修改)
2020/12/25 Python
浅谈HTML5 defer和async的区别
2016/06/07 HTML / CSS
HTML5 贪吃蛇游戏实现思路及源代码
2013/09/03 HTML / CSS
html5摇一摇代码优化包括DeviceMotionEvent等等
2014/09/01 HTML / CSS
Booking.com荷兰:全球酒店网上预订
2017/08/22 全球购物
计算机专业应届毕业生自荐信
2013/09/26 职场文书
超市总经理岗位职责
2014/02/02 职场文书
建国大业观后感800字
2015/06/01 职场文书
2015年秋季运动会加油稿
2015/07/22 职场文书
干部理论学习心得体会
2016/01/21 职场文书