在我们日常开发中,操作和转换数组是一件很常见的操作,下面我们来看一个实例:
复制代码 代码如下:
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);