题目 20 / 31
把 obj.foo 传进另一个函数,会把 obj 一起带过去吗?
知识点: this 绑定难度: 进阶
函数实参只是一个值——它原来的接收者从来都不是这个值的一部分。
使用执行可视化器解题在下方逐步观察每个绑定、函数调用和控制台输出。预测输出结果
预测两行输出。doFoo 接收 obj.foo 作为参数 fn 并调用 fn()——fn 还记得 obj 吗?
function foo() {
console.log(this.a);
}
function doFoo(fn) {
console.log(this);
fn();
}
var obj = { a: 1, foo };
var a = 2;
doFoo(obj.foo);查看答案与完整解析
正确输出
window
2为什么会这样
doFoo(obj.foo) 在顶层被调用,调用语法里没有接收者,因此 doFoo 内部默认绑定生效:this 是全局对象,console.log(this) 打印出它。
obj.foo 在传递时只是被当作一个值——一个指向函数对象的引用。参数 fn 保存的是同一个函数对象,完全不记得 obj。
在 doFoo 内部,fn() 是一次裸的、无接收者的调用,默认绑定再次生效:this.a 读到的是全局变量 a,也就是 2。
这道题考察什么
- this 绑定从不会随着函数值一起传递
- 每一次调用表达式都会根据自己的语法重新决定 this
- 不管函数是怎么传过来的,只要调用没有接收者,默认绑定就会生效
运行环境前提
假设运行在经典的非严格模式脚本中,两次无接收者的调用里,this 都由全局对象充当。