You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于Array.reduce()分组示例中.bind()用法的两个疑问

Array.reduce() 分组示例的常见疑问解答

先看这段用Array.reduce()按站点分组的示例代码:

var stats = [
  { site: "google.fr", browser: "Chrome", value: "50%" },
  { site: "google.fr", browser: "FireFox", value: "30%" },
  { site: "google.fr", browser: "Internet Explorer", value: "20%" },
  { site: "mozilla.fr", browser: "FireFox", value: "60%" },
  { site: "mozilla.fr", browser: "Internet Explorer", value: "20%" },
  { site: "microsoft.fr", browser: "Chrome", value: "10%" },
  { site: "microsoft.fr", browser: "FireFox", value: "20%" },
];
function compareSite(site, item) {
  return site === item.site;
}
function containSite(site, items) {
  return items.some(compareSite.bind(null, site));
}
function groupBySite(memo, item) {
  var site = memo.filter(containSite.bind(null, item.site));
  if (site.length > 0) {
    site[0].push(item);
  } else {
    memo.push([item]);
  }
  return memo;
}
// We use an empty array as accumulator
var results = stats.reduce(groupBySite, []);
console.log(results);

运行结果:

[
  [
    { site: 'google.fr', browser: 'Chrome', value: '50%' },
    { site: 'google.fr', browser: 'FireFox', value: '30%' },
    { site: 'google.fr', browser: 'Internet Explorer', value: '20%' }
  ],
  [
    { site: 'mozilla.fr', browser: 'FireFox', value: '60%' },
    { site: 'mozilla.fr', browser: 'Internet Explorer', value: '20%' }
  ],
  [
    { site: 'microsoft.fr', browser: 'Chrome', value: '10%' },
    { site: 'microsoft.fr', browser: 'FireFox', value: '20%' }
  ]
]

接下来解答你的两个疑问:

疑问1:为什么在containSite函数中必须使用.bind(null, site)?

首先得回忆Array.some()的回调规则:它会把遍历到的数组元素、索引、原数组依次作为参数传给回调函数。而我们的compareSite函数定义是(site, item)——第一个参数是要匹配的站点,第二个是要检查的元素。

如果直接把compareSite传给some,some会把数组元素当成第一个参数传给它,这就和compareSite的参数顺序完全反了!

用bind(null, site)的作用,就是把site固定成compareSite的第一个参数,同时把null作为this的指向(这里我们不需要用到this,所以传null就行)。这样当some调用这个绑定后的函数时,就会把数组元素作为第二个参数传进去,刚好匹配compareSite的参数顺序,实现“检查当前数组里有没有元素的site等于指定site”的逻辑。

疑问2:为什么在groupBySite函数中使用的是.bind(null, item.site)而非之前的.bind(null, site)?

这里的核心是绑定的是当前遍历的元素的站点。

在groupBySite里,item是stats数组中正在被处理的当前元素,item.site就是这个元素所属的站点。我们需要调用containSite来检查:memo(已经分组好的数组集合)里有没有已经存在这个站点的分组。

而containSite的第一个参数需要的是“要查找的站点”,所以这里必须把当前item的site绑定进去,而不是一个固定的site变量——毕竟每个元素的站点可能不一样,我们要动态匹配当前元素的站点。

简单说,这里的item.site是随遍历过程动态变化的,每次处理不同的item,绑定的站点值就不同,这样才能正确把每个元素分到对应的站点组里。


内容的提问来源于stack exchange,提问作者Gron465

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 20:24:03