题目 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 参数都是这些数组方法规范行为的一部分。