html5中文学习网

您的位置: 首页 > 网站及特效实例 > javascript特效 » 正文

Javascript中Array.prototype.map()详解_基础知识_

[ ] 已经帮助:人解决问题

在我们日常开发中,操作和转换数组是一件很常见的操作,下面我们来看一个实例:ELFHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
ELFHTML5中文学习网 - HTML5先行者学习网
var desColors = [],ELFHTML5中文学习网 - HTML5先行者学习网
    srcColors = [ELFHTML5中文学习网 - HTML5先行者学习网
        {r: 255, g: 255, b: 255 }, // WhiteELFHTML5中文学习网 - HTML5先行者学习网
        {r: 128, g: 128, b: 128 }, // GrayELFHTML5中文学习网 - HTML5先行者学习网
        {r: 0,   g: 0,   b: 0   }  // BlackELFHTML5中文学习网 - HTML5先行者学习网
    ];ELFHTML5中文学习网 - HTML5先行者学习网

for (var i = 0, ilen = srcColors.length; i < ilen; i++) {ELFHTML5中文学习网 - HTML5先行者学习网
    var color = srcColors[i],ELFHTML5中文学习网 - HTML5先行者学习网
        format = function(color) {ELFHTML5中文学习网 - HTML5先行者学习网
            return Math.round(color / 2);ELFHTML5中文学习网 - HTML5先行者学习网
        };ELFHTML5中文学习网 - HTML5先行者学习网

    desColors.push( {ELFHTML5中文学习网 - HTML5先行者学习网
        r: format(color.r),ELFHTML5中文学习网 - HTML5先行者学习网
        g: format(color.g),ELFHTML5中文学习网 - HTML5先行者学习网
        b: format(color.b)ELFHTML5中文学习网 - HTML5先行者学习网
    });ELFHTML5中文学习网 - HTML5先行者学习网
}ELFHTML5中文学习网 - HTML5先行者学习网

// Outputs:ELFHTML5中文学习网 - HTML5先行者学习网
// [ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 128, g: 128, b: 128 },ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 64,  g: 64,  b: 64  },ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 0,   g: 0,   b: 0   }ELFHTML5中文学习网 - HTML5先行者学习网
// ];ELFHTML5中文学习网 - HTML5先行者学习网
console.log(desColors);ELFHTML5中文学习网 - HTML5先行者学习网

ELFHTML5中文学习网 - HTML5先行者学习网
ELFHTML5中文学习网 - HTML5先行者学习网

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

复制代码 代码如下:
ELFHTML5中文学习网 - HTML5先行者学习网
var srcColors = [ELFHTML5中文学习网 - HTML5先行者学习网
        {r: 255, g: 255, b: 255 }, // WhiteELFHTML5中文学习网 - HTML5先行者学习网
        {r: 128, g: 128, b: 128 }, // GrayELFHTML5中文学习网 - HTML5先行者学习网
        {r: 0,   g: 0,   b: 0   }  // BlackELFHTML5中文学习网 - HTML5先行者学习网
    ],ELFHTML5中文学习网 - HTML5先行者学习网
    desColors = srcColors.map(function(val) {ELFHTML5中文学习网 - HTML5先行者学习网
        var format = function(color) {ELFHTML5中文学习网 - HTML5先行者学习网
            return Math.round(color/2);ELFHTML5中文学习网 - HTML5先行者学习网
        };ELFHTML5中文学习网 - HTML5先行者学习网
        return {ELFHTML5中文学习网 - HTML5先行者学习网
            r: format(val.r),ELFHTML5中文学习网 - HTML5先行者学习网
            g: format(val.g),ELFHTML5中文学习网 - HTML5先行者学习网
            b: format(val.b)ELFHTML5中文学习网 - HTML5先行者学习网
        }ELFHTML5中文学习网 - HTML5先行者学习网
    });ELFHTML5中文学习网 - HTML5先行者学习网
// Outputs:ELFHTML5中文学习网 - HTML5先行者学习网
// [ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 128, g: 128, b: 128 },ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 64,  g: 64,  b: 64  },ELFHTML5中文学习网 - HTML5先行者学习网
//    {r: 0,   g: 0,   b: 0   }ELFHTML5中文学习网 - HTML5先行者学习网
// ];ELFHTML5中文学习网 - HTML5先行者学习网
console.log(desColors);ELFHTML5中文学习网 - HTML5先行者学习网
ELFHTML5中文学习网 - HTML5先行者学习网

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

1.map基本定义:ELFHTML5中文学习网 - HTML5先行者学习网
array.map(callback[, thisArg]);ELFHTML5中文学习网 - HTML5先行者学习网

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

callback 函数会被自动传入三个参数:数组元素,元素索引,原数组本身。ELFHTML5中文学习网 - HTML5先行者学习网

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

map 不修改调用它的原数组本身(当然可以在 callback 执行时改变原数组)。ELFHTML5中文学习网 - HTML5先行者学习网

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

2.map实例:ELFHTML5中文学习网 - HTML5先行者学习网

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

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

复制代码 代码如下:
ELFHTML5中文学习网 - HTML5先行者学习网
//实例二:下面的操作结果是什么?ELFHTML5中文学习网 - HTML5先行者学习网
var result = ["1", "2", "3"].map(parseInt);ELFHTML5中文学习网 - HTML5先行者学习网
//Outputs: [1, NaN, NaN] ELFHTML5中文学习网 - HTML5先行者学习网
console.log(result);ELFHTML5中文学习网 - HTML5先行者学习网
ELFHTML5中文学习网 - HTML5先行者学习网

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

复制代码 代码如下:
ELFHTML5中文学习网 - HTML5先行者学习网
//Ouputs: 1ELFHTML5中文学习网 - HTML5先行者学习网
console.log(parseInt("1", 0));ELFHTML5中文学习网 - HTML5先行者学习网
//Ouputs: 1ELFHTML5中文学习网 - HTML5先行者学习网
console.log(parseInt("1", undefined));ELFHTML5中文学习网 - HTML5先行者学习网
//Ouputs: NaNELFHTML5中文学习网 - HTML5先行者学习网
console.log(parseInt("2", 1));ELFHTML5中文学习网 - HTML5先行者学习网
//Ouputs: NaNELFHTML5中文学习网 - HTML5先行者学习网
console.log(parseInt("3", 2));ELFHTML5中文学习网 - HTML5先行者学习网
ELFHTML5中文学习网 - HTML5先行者学习网

后面两个很容易理解,但是前两个为什么返回1呢?为了解释这个问题,我们看看官方的描述:ELFHTML5中文学习网 - HTML5先行者学习网
If radix is undefined or 0 (or absent), JavaScript assumes the following:ELFHTML5中文学习网 - HTML5先行者学习网
a) If the input string begins with “0x” or “0X”, radix is 16 (hexadecimal) and the remainder of the string is parsed.ELFHTML5中文学习网 - HTML5先行者学习网
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.ELFHTML5中文学习网 - HTML5先行者学习网
c) If the input string begins with any other value, the radix is 10 (decimal).ELFHTML5中文学习网 - HTML5先行者学习网
在第三点中当string为其他值时,进制默认为10。ELFHTML5中文学习网 - HTML5先行者学习网

那么我们如何修改才能使上例正常输出呢?看下例:ELFHTML5中文学习网 - HTML5先行者学习网

复制代码 代码如下:
ELFHTML5中文学习网 - HTML5先行者学习网
var result = ["1", "2", "3"].map(function(val) {ELFHTML5中文学习网 - HTML5先行者学习网
    return parseInt(val, 10);ELFHTML5中文学习网 - HTML5先行者学习网
});ELFHTML5中文学习网 - HTML5先行者学习网
//Outputs: [1, 2, 3] ELFHTML5中文学习网 - HTML5先行者学习网
console.log(result);ELFHTML5中文学习网 - HTML5先行者学习网
ELFHTML5中文学习网 - HTML5先行者学习网

3.map方法的兼容性:ELFHTML5中文学习网 - HTML5先行者学习网
map方法在IE8及以下浏览器不支持,要想兼容老版本的浏览器,可以:ELFHTML5中文学习网 - HTML5先行者学习网

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.ELFHTML5中文学习网 - HTML5先行者学习网

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

(责任编辑:)
推荐书籍
推荐资讯
关于HTML5先行者 - 联系我们 - 广告服务 - 友情链接 - 网站地图 - 版权声明 - 人才招聘 - 帮助