题目 22 / 31

filter 的第二个参数如何改变回调里的 this?

知识点: this 绑定难度: 进阶

部分数组遍历方法接受一个可选的 thisArg 参数,用来覆盖回调函数的 this。

使用执行可视化器解题在下方逐步观察每个绑定、函数调用和控制台输出。

预测输出结果

预测三行输出。回调只是一个普通函数——它是怎么读到 obj.a 的?

var obj = { a: 'obj' };
var a = 'window';
var arr = [1, 2, 3];

arr.filter(function (item) {
  console.log(item, this.a);
  return item > 2;
}, obj);
查看答案与完整解析

正确输出

1 obj
2 obj
3 obj

为什么会这样

Array.prototype.filter 接受一个可选的第二参数 thisArg。规范规定,一旦提供了它,调用回调时就会使用这个值作为 this,而不是裸调用本来会产生的默认绑定。

这里传入的 thisArg 是 obj,因此对每个元素来说,回调内部的 this 都被显式设置为 obj,this.a 每次都读到 "obj"。

filter 依然会对数组的每个元素各调用一次回调(先是 1,然后 2,最后 3),每次都把元素和 this.a 一起打印出来,于是三行都输出 "obj"。

这道题考察什么

  • forEach、map、filter、some、every 都接受可选的 thisArg
  • thisArg 会覆盖回调内部本来的默认绑定
  • 这次 this 的替换是数组方法内部按每次调用安排的,而不是源码里写出来的调用语法决定的

运行环境前提

在任何标准 JavaScript 环境中,thisArg 参数都是这些数组方法规范行为的一部分。

规范参考

JavaScript 代码编辑器支持直接编辑或粘贴自定义代码
第 0 步 / 共 0 步
单步Space播放
按 → 单步 或 Space 自动播放
阶段 1: 编译预解析(变量提升与内存分配)
阶段 2: 代码执行(逐行赋值与调用求值)
单步执行原理解析

按键盘右方向键 “→” 进行单步调试,或按空格键 “Space” / 点击 “▶ 自动播放” 进行连续执行。