Array.prototype.map()
基线 广泛可用
此功能已成熟稳定,并在许多设备和浏览器版本中正常运行。它自 2015 年 7 月.
报告反馈
尝试一下
语法
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。map(callbackFn)
map(callbackFn, thisArg)
js
参数
-
callbackFn
一个要对数组中的每个元素执行的函数。它的返回值被添加为新数组中的单个元素。该函数使用以下参数调用
-
element
数组中正在处理的当前元素。
-
index
数组中正在处理的当前元素的索引。
-
array
- 调用
map()
的数组。 -
thisArg
可选
在执行 callbackFn
时用作 this
的值。参见 迭代方法。
返回值
描述
示例
由于 map
构建了一个新数组,因此在不使用返回的数组的情况下调用它是一种反模式;请改用 forEach
或 for...of
。
将数字数组映射到平方根数组
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const numbers = [1, 4, 9];
const roots = numbers.map((num) => Math.sqrt(num));
// roots is now [1, 2, 3]
// numbers is still [1, 4, 9]
以下代码获取一个数字数组,并创建一个包含第一个数组中数字平方根的新数组。
使用 map 重新格式化数组中的对象
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const kvArray = [
{ key: 1, value: 10 },
{ key: 2, value: 20 },
{ key: 3, value: 30 },
];
const reformattedArray = kvArray.map(({ key, value }) => ({ [key]: value }));
console.log(reformattedArray); // [{ 1: 10 }, { 2: 20 }, { 3: 30 }]
console.log(kvArray);
// [
// { key: 1, value: 10 },
// { key: 2, value: 20 },
// { key: 3, value: 30 }
// ]
以下代码获取一个对象数组,并创建一个包含重新格式化的新对象的数组。
使用 parseInt() 与 map()
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。["1", "2", "3"].map(parseInt);
通常使用带有一个参数(正在遍历的元素)的回调函数。某些函数通常也只带有一个参数使用,即使它们接受其他可选参数。这些习惯可能导致令人困惑的行为。请考虑
虽然可能预期结果为 [1, 2, 3]
,但实际结果是 [1, NaN, NaN]
。
parseInt
通常使用一个参数,但它接受两个参数。第一个是表达式,第二个是基数,而回调函数 Array.prototype.map
传递 3 个参数:元素、索引和数组。第三个参数被 parseInt
忽略,但不是第二个参数!这是潜在混淆的根源。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。/* first iteration (index is 0): */ parseInt("1", 0); // 1
/* second iteration (index is 1): */ parseInt("2", 1); // NaN
/* third iteration (index is 2): */ parseInt("3", 2); // NaN
以下是迭代步骤的简要示例
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。["1", "2", "3"].map((str) => parseInt(str, 10)); // [1, 2, 3]
要解决这个问题,请定义另一个只接受一个参数的函数
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。["1", "2", "3"].map(Number); // [1, 2, 3]
// But unlike parseInt(), Number() will also return a float or (resolved) exponential notation:
["1.1", "2.2e2", "3e300"].map(Number); // [1.1, 220, 3e+300]
// For comparison, if we use parseInt() on the array above:
["1.1", "2.2e2", "3e300"].map((str) => parseInt(str, 10)); // [1, 2, 3]
你也可以使用 Number
函数,它只接受一个参数
有关更多讨论,请参见 Allen Wirfs-Brock 的 A JavaScript optional argument hazard。
映射的数组包含 undefined
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const numbers = [1, 2, 3, 4];
const filteredNumbers = numbers.map((num, index) => {
if (index < 3) {
return num;
}
});
// index goes from 0, so the filterNumbers are 1,2,3 and undefined.
// filteredNumbers is [1, 2, 3, undefined]
// numbers is still [1, 2, 3, 4]
当返回 undefined
或任何内容时,结果数组将包含 undefined
。如果你想删除该元素,请链接一个 filter()
方法,或使用 flatMap()
方法并返回一个空数组来表示删除。
有副作用的映射
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const cart = [5, 15, 25];
let total = 0;
const withTax = cart.map((cost) => {
total += cost;
return cost * 1.2;
});
console.log(withTax); // [6, 18, 30]
console.log(total); // 45
回调函数可以有副作用。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const cart = [5, 15, 25];
const total = cart.reduce((acc, cost) => acc + cost, 0);
const withTax = cart.map((cost) => cost * 1.2);
不建议这样做,因为复制方法最好与纯函数一起使用。在这种情况下,我们可以选择对数组进行两次迭代。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const products = [
{ name: "sports car" },
{ name: "laptop" },
{ name: "phone" },
];
products.map((product) => {
product.price = 100;
});
有时这种模式会走到极端,map()
唯一有用的功能就是引起副作用。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。products.forEach((product) => {
product.price = 100;
});
如前所述,这是一种反模式。如果你不使用 map()
的返回值,请改用 forEach()
或 for...of
循环。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const productsWithPrice = products.map((product) => {
return { ...product, price: 100 };
});
或者,如果你想创建一个新数组
使用 callbackFn 的第三个参数
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const numbers = [3, -1, 1, 4, 1, 5, 9, 2, 6];
const averaged = numbers
.filter((num) => num > 0)
.map((num, idx, arr) => {
// Without the arr argument, there's no way to easily access the
// intermediate array without saving it to a variable.
const prev = arr[idx - 1];
const next = arr[idx + 1];
let count = 1;
let total = num;
if (prev !== undefined) {
count++;
total += prev;
}
if (next !== undefined) {
count++;
total += next;
}
const average = total / count;
// Keep two decimal places
return Math.round(average * 100) / 100;
});
console.log(averaged); // [2, 2.67, 2, 3.33, 5, 5.33, 5.67, 4]
array
参数在你想访问数组中的另一个元素时很有用,尤其是在你没有引用该数组的现有变量时。以下示例首先使用 filter()
提取正值,然后使用 map()
创建一个新数组,其中每个元素都是其邻居和自身的平均值。
array
参数不是正在构建的数组——无法从回调函数中访问正在构建的数组。
在稀疏数组上使用 map()
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。console.log(
[1, , 3].map((x, index) => {
console.log(`Visit ${index}`);
return x * 2;
}),
);
// Visit 0
// Visit 2
// [2, empty, 6]
稀疏数组在 map()
后仍然是稀疏的。返回的数组中空槽的索引仍然为空,回调函数不会在它们上调用。
在非数组对象上调用 map()
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const arrayLike = {
length: 3,
0: 2,
1: 3,
2: 4,
3: 5, // ignored by map() since length is 3
};
console.log(Array.prototype.map.call(arrayLike, (x) => x ** 2));
// [ 4, 9, 16 ]
map()
方法读取 this
的 length
属性,然后访问每个键为非负整数且小于 length
的属性。
map()
方法用于 Array
实例,它创建一个新的数组,该数组填充了对调用数组中每个元素调用提供的函数的结果。const elems = document.querySelectorAll("select option:checked");
const values = Array.prototype.map.call(elems, ({ value }) => value);
此示例展示了如何遍历由 querySelectorAll
收集的对象集合。这是因为 querySelectorAll
返回一个 NodeList
(这是对象的集合)。在这种情况下,我们在屏幕上返回所有选定的 option
的值
规范
你也可以使用 Array.from() 将 elems 转换为数组,然后访问 map() 方法。 |
---|
规范 # ECMAScript 语言规范 |
浏览器兼容性
sec-array.prototype.map