首页 > 解决方案 > 为什么reduce中谓词函数需要包装函数?

问题描述

我正在玩 Array.reduce 和 Set 之间的交互,我注意到以下奇怪的行为。

通常这是有效的:

console.log(
  Set.prototype.add.call(new Set(), 1, 0, [])
);
// Set { 1 }

但是,如果我将其与 reduce 结合起来,则以下内容不起作用:

console.log(
  [1,2,3].reduce(Set.prototype.add.call, new Set())
);
// TypeError: undefined is not a function
//     at Array.reduce (<anonymous>)

但是,如果我将谓词函数包装在包装器中,这将起作用:

console.log(
  [1,2,3].reduce((...args) => Set.prototype.add.call(...args), new Set())
);
// Set { 1, 2, 3 }

我在不同的 JS 引擎(Chrome 和 Safari)上尝试了这个并得到了相同的结果,所以它可能不是引擎特定的行为。这同样适用于 Map 对象。我无法弄清楚为什么会这样。

标签: javascriptnode.jsecmascript-5

解决方案


没有包装,你Set.prototype.add.call会失去它的this价值(应该是Set.prototype.add函数,而是设置为undefined)。

尝试这个:

[1,2,3].reduce(Set.prototype.add.call.bind(Set.prototype.add), new Set());

请参阅http://speakingjs.com/es5/ch01.html#_extracting_methods


推荐阅读