题目 19 / 31
为什么最后一行什么都没打印?
知识点: this 绑定难度: 进阶
call 和 apply 会立即以指定的 this 调用函数;bind 只是返回一个新函数。
使用执行可视化器解题在下方逐步观察每个绑定、函数调用和控制台输出。预测输出结果
预测输出。四行代码看起来都在调用 foo——真的都调用了吗?数一数实际出现了几行 console.log。
function foo() {
console.log(this.a);
}
var obj = { a: 1 };
var a = 2;
foo();
foo.call(obj);
foo.apply(obj);
foo.bind(obj);查看答案与完整解析
正确输出
2
1
1为什么会这样
foo() 是一次无接收者的调用,默认绑定生效:this 是全局对象,this.a 读到的是全局变量 a,也就是 2。
foo.call(obj) 和 foo.apply(obj) 都属于显式绑定——它们会立即以 this 被强制指定为 obj 的方式调用 foo,因此两次 this.a 都读到 1。
foo.bind(obj) 根本没有调用 foo。它只是同步地返回一个全新的绑定函数,把 obj 永久附加为它的 this。由于这个返回的函数从未被调用,foo 的函数体不会第四次执行,这一行也就没有任何输出。
这道题考察什么
- call 和 apply 会立即以显式指定的 this 调用函数
- bind 返回一个新函数,而不是调用原函数
- 绑定函数的 this 之后无法被再次的 call、apply 或 bind 覆盖
运行环境前提
假设运行在经典的非严格模式脚本中,默认绑定解析为全局对象,而不是 undefined。