0
点赞
收藏
分享

微信扫一扫

数组的Map方法详解


作用

​map()​​:创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。

语法

​arr.map(callback(currentValue [, index [, array]]){ // Return element for new_array }[, thisArg])​

  • ​callback​​:生成新数组元素的函数,该函数接收一至三个参数:
  • ​currentValue​​:数组中正在处理的当前元素。
  • ​index​​: 可选,数组中正在处理的当前元素的索引。
  • ​array​​​: 可选,​​map​​ 方法正在操作的数组。

​thisArg​​​: 可选,执行 ​​callback​​​ 函数时值被用作 ​​this​

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

  • ​map​​​ 方法会给原数组中的每个元素都按顺序调用一次​​callback​​ 函数。
  • ​callback​​​ 每次执行后的返回值(包括​​undefined​​)组合起来形成一个新数组。
  • ​callback​​​ 函数只会在有值的索引上被调用;那些从来没被赋过值或者使用​​delete​​ 删除的索引则不会被调用。
  • ​map​​​ 不修改调用它的原数组本身(当然可以在​​callback​​ 执行时改变原数组)

因为 ​​map​​​ 生成一个新数组,当你不打算使用返回的新数组却使用请用 ​​forEach​​​ 或者 ​​for-of​​ 替代。

使用示例

求数组中每个元素的平方根

const numbers = [1, 4, 9];
const roots = numbers.map(Math.sqrt);
console.log(roots); // [1, 2, 3]

上述的代码在 ​​map​​​ 中传入了一个 ​​Math.sqrt​​​ 然后就计算出了 numbers 每个元素的平方根,那么它是如何实现的?
看如图所示,可以发现 ​​​Math.sqrt​​​ 实际上是一个函数,然后接收一个 ​​number​​ 类型的参数,在此示例中可以这么认为

const roots = numbers.map(function (item) {
// 这里面就是 Math.sqrt 函数做的操作,它将返回每一个 item 的平方根
});


数组的Map方法详解_javascript

返回的数组元素中存在 undefined

const numbers = [1, 2, 3, 4, 5];
const filteredNumbers = numbers.map(function (num,) {
if (index < 3) {
return num;
}
});

console.log(filteredNumbers);


数组的Map方法详解_数组_02

在 map 中改变了原数组

基础数据类型的数组,如代码与结果所示,基础类型的数组在修改 ​​item​​​ 时并不会改变原数组。
是因为 ​​​map​​​ 方法处理数组元素的范围是在 ​​callback​​ 方法第一次调用之前就已经确定了。

const arr = [1, 5, 10, 15, 66, 200];

const newArr = arr.map(function (item) {
if (item > 15) {
item += 1
}
return item
});

console.log(arr);
console.log(newArr);


数组的Map方法详解_typescript_03

对象数组,如代码与结果所示,对象数组在修改 ​​item​​ 时会改变原数组

const arr = [
{ name: 'wfly', age: 18 },
{ name: 'fly', age: 8 },
{ name: 'fnn', age: 18 },
];

const newArr = arr.map(function (item) {
if (item.name.includes('fly')) {
item.age += 1
}
return item
});

console.log(arr);
console.log(newArr);


数组的Map方法详解_数组元素_04

使用过程中直接改变原数组

  • ​map​​​ 方法处理数组元素的范围是在​​callback​​ 方法第一次调用之前就已经确定了。
  • 调用​​map​​ 方法之后追加的数组元素不会被​​callback​​ 访问。
  • 如果存在的数组元素改变了,那么传给​​callback​​​ 的值是​​map​​​ 访问该元素时的值。在​​map​​ 函数调用后但在访问该元素前,该元素被删除的话,则无法被访问到。

const arr = [3, 5, 10, 15, 66, 200];

const newArr = arr.map(function (item,) {
arr[index] = arr[index] + 10
arr.push(999)
console.log('当前 arr 的值:', arr);
arr.unshift(111)
return item
});

console.log(arr);
console.log(newArr);


数组的Map方法详解_typescript_05

如结果所示,会发现 ​​newArr​​​ 输出的是 ​​[3, 13, 23, 33, 43, 53]​​​,为什么会造成这种现象,
我们在示例代码中每一次 ​​​callback​​​ 的执行,都会将原数组的 ​​arr​​​ 对象的 ​​index​​​ 项 ​​+10​​​,同时我们每一次执行 ​​callback​​​ 都会在给原数组 ​​push​​​ 一个元素以及 ​​unshift​​​ 的一个元素
当然由于 ​​​push​​​ 是在尾部添加,它不会被 ​​callback​​​ 所访问,但是 ​​unshift​​​ 是在头部添加,会导致原数组之前的元素每执行一次 ​​callback​​​ 都会向后移一项
由于 ​​​callback​​​ 的 ​​item​​​,每次都是访问当前项的元素,而恰好 ​​3​​​ 这个元素每次都是 ​​+10​​​ 然后向后移一项,
所以得出结果 ​​​[3, 13, 23, 33, 43, 53]​

所以上述的代码示例如果没有添加 unshift 去改变原数组的话,输出的结果就是 ​​[3, 5, 10, 15, 66, 200]​

map + ​parseInt​ 问题

["1", "2", "3"].map(parseInt); // [1, NaN, NaN]

如果看完第一个示例这个问题就很容易明白,parseInt 是一个函数,但是它接受的参数是两个,所以它不会输出 [1, 2, 3],
它在处理时实际上是 ​​​parseInt(1, 0)​​​,​​parseInt(2, 1)​​​,​​parseInt(3, 2)​​​,第一项参数是数组的 ​​item​​,第二个参数是当前数组的索引

正确的处理方法应该如下

['1', '2', '3'].map(str => parseInt(str));


举报

相关推荐

0 条评论