JavaScript数组原型.map方法何时/为什么使用第三个参数?

3
我最近注意到,当使用array.prototype.map()时,我的回调函数可能会接受第三个参数,这是我正在映射的数组。我想知道是否有任何用例适用于此参数,因为在回调函数内部,可以访问该数组。
如果我在回调函数内部访问正在映射的数组,那么为什么/何时应该使用第三个参数而不是直接访问该数组?
即使我能想象出每种情况下这两种方法都可以正常工作,但我想知道哪种方法是推荐的以及原因。 示例

2
简而言之,你可能无法访问数组,或者你可能不想引用它。情况1:myArr.filter(x => x % 2 == 1).map((x, i, arr) => x+arr.length) - 这是一个链式操作,所以在第一个链结束后,你不能再引用myArr作为你的工作数据。你可以停止链式操作,将其赋值给一个变量并使用,但这有点浪费。情况2:你的回调函数与你拥有的数组处于不同的作用域中。在一个地方,你有callback = (x, i, arr) => x+arr.length,在另一个地方你使用myArr.map(callback),所以你不能在回调函数中引用原始数组。 - VLAZ
3个回答

8
第三个参数在链式使用多个数组方法并需要访问数组的中间状态(即前一个操作的结果)时很有用:
const source = [-3,-2,-1,0,1,2,3,4,5];
source
  .filter(n => n >= 0)
  .map((n, index, arr) => {
     // arr contains only non-negative numbers
     // here you may have some logic that rely on it
     return n;
  })

5

编辑: 这个答案已经(巧合地)在被标记为重复的问题中给出。请到那里查看。


你可能希望以一种通用的方式引用原始数组。例如,回调函数可以是单独的函数,而不仅仅是通常所见的匿名函数:

function arrayMapper(val, idx, arr) {
  // Some operations which use arr
}

myArray.map(arrayMapper);
myOtherArray.map(arrayMapper);

请注意,在执行arrayMapper时,arr参数是指向外部范围中的不同数组的。

这里的结果仍然与示例在全局上下文中相同。在这里,我仍然可以访问原始的myArray,而不需要第三个参数。请查看我的答案,它描述了在面向对象编程中使用函数的更可能的用法。 - vipul patel
@vipulpatel 这个更新是否使我的意图更清晰? - MTCoster
是的,在这里我可以看到如果我们使用不同的函数来处理两个不同的数组。你也可以看到我的例子,使用面向对象编程,因为现在没有人在全局范围内使用ES6或TypeScript编写代码,而且还有许多其他提供了类似的编程风格。 - vipul patel

0

你正在使用普通的全局上下文,这种情况下不需要考虑这个问题。请看下面的例子,在面向对象的函数编程中,你没有使用箭头函数(它保留了当前上下文)。在那种情况下,它作为第三个属性很有帮助。在第一个例子中,我无法在匿名函数中访问this.numbers,因为匿名函数有自己的上下文。在这种情况下,当你想要访问原始数组进行操作时,它非常有用。

工作示例:

function Demo (numbers){
   this.numbers = numbers;
}

Demo.prototype.doMap = function () {
 return this.numbers.map(function(num, index, array) {
     return array[num]
  });
}

var obj  = new Demo([1, 2, 4, 2, 3]);

console.log(obj.doMap()); // will work

非工作示例 如果我不传递数组,它会抛出错误。

function Demo (numbers){
   this.numbers = numbers;
}

Demo.prototype.doMap = function () {
 return this.numbers.map(function(num, index, array) {
     return this.numbers[num] // cant access original number array using this (this refers to context of anonymous function)
  });
}

var obj  = new Demo([1, 2, 4, 2, 3]);

console.log(obj.doMap()); // throw error


这是传递给map函数的第二个参数。OP在谈论回调函数中提供的第三个参数 - 数组本身 arr.map(function (item, index, array) {}, thisArg) - VLAZ
抱歉!我刚得到这个问题并更新了答案 :) - vipul patel
@VLAZ 嗨,现在有意义了吗? - vipul patel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接