跳到主要内容

map

2023年06月17日
柏拉文
越努力,越幸运

一、认识


Array.prototype.map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

二、语法


var new_array = arr.map(function callback(currentValue[, index[, array]]) {
// Return element for new_array
}[, thisArg])
  • callback: 生成新数组元素的函数,使用三个参数:
    • currentValue: callback 数组中正在处理的当前元素。
    • index可选: callback 数组中正在处理的当前元素的索引。
    • array可选: map 方法调用的数组。
  • thisArg可选: 执行 callback 函数时值被用作this。

三、返回值


一个由原数组每个元素执行回调函数的结果组成的新数组。

四、综合对比


4.1 for-in vs for-of vs forEach vs Map

  • map: 只能遍历数组,不能中断,返回值是修改后的数组;

  • forEach: 只能遍历数组; 没有返回值(或认为返回值是undefined); 无法中途跳出forEach循环,break命令或return命令都不能奏效;

  • for...in循环: 遍历获得键名,且遍历的结果都是字符串(尽管数组元素索引值为 Number 类型); 遍历对象自身的和继承的可枚举的属性; 中途可以跳出循环;

  • for...of循环: 遍历获得键值; 中途可以跳出循环; 提供了遍历所有数据结构的统一操作接口, 一个数据结构只要在Symbol.iterator属性上部署了Iterator接口, 就可以用for...of循环遍历它的成员;

五、应用场景


5.1 ["1","2","3"].map(fun) 技巧,使最后的结果为 [1,2,3]

  • 解决方案一、直接使用["1","2","3"].map(parseInt)(错误方案)

    const result = ["1","2","3"].map(parseInt);
    console.log(result); // 结果为 [1, NaN, NaN]

    原因:

    ["1","2","3"].map(parseInt)  => ["1","2","3"].map((value,index,array)=> parseInt(value,index));

    parseInt("1",0); // 0 为失效的进制位,所以转化为十进制, 结果为 1
    parseInt("2",1); // 1 进制不可能有 2 ,所以为 NaN
    parseInt("3",2); // 2 进制不可能有 3 , 所以为 NaN

    总结: 不可以直接使用[].map(parseInt)方案来转化整数

  • 解决方案二、通过函数包装parseInt

    // 解决方案一 
    function formateInt(item){
    return parseInt(item,10);
    }
    const result = ["1","2","3"].map(formateInt);
    console.log(result); // 输出 [1,2,3]
  • 解决方案三、通过Number()替代parseInt()

    ['1', '2', '3'].map(Number);

5.2 map 不对未初始化的值进行任何操作

const array = [1,,,,,,,3];
const arrayCopy = array.map(v=>{
return v+'哈哈'
});
console.log(arrayCopy); // ['1哈哈', empty × 6, '3哈哈']

5.3 map 中如果没有返回任何内容,返回 undefined

const array = [1,2,3,4,5];
const result = array.map(function(currentValue,index,arr){
if(currentValue<4){
return currentValue
}
});
console.log(result); // 结果为  [1, 2, 3, undefined, undefined]

六、原理(Polyfill)


Array.prototype.map = function(callback,thisArg){
if(this == null){
throw new TypeError('this is null or not defined');
}
if(typeof callback !== 'function'){
throw new TypeError('callback is not function');
}
var object = Object(this);
var length = object.length >>> 0;
var result = new Array(length);
var index = 0;
while(index < length){
if(index in object){
var value = object[index];
var res = callback.call(thisArg,value,index,object);
result[index] = res;
}
index++;
}
return result;
}

const array = [1,,,,,,,3];
const arrayCopy = array.map(v=>{
return v+'哈哈'
});
console.log(arrayCopy); // ['1哈哈', empty × 6, '3哈哈']