题目 18 / 31
为什么箭头函数属性读不到对象上的值?
知识点: this 绑定难度: 进阶
和简写方法不同,箭头函数永远不会把自己的 this 绑定到持有它的对象上。
使用执行可视化器解题在下方逐步观察每个绑定、函数调用和控制台输出。预测输出结果
预测两行输出。greet 和 farewell 是同一个对象上的两个属性——为什么它们解析 this 的方式不一样?
const object = {
who: 'World',
greet() {
return `Hello, ${this.who}!`;
},
farewell: () => {
return `Goodbye, ${this.who}!`;
}
};
console.log(object.greet());
console.log(object.farewell());查看答案与完整解析
正确输出
Hello, World!
Goodbye, undefined!为什么会这样
greet 用的是简写方法语法,本质是一个普通函数。调用 object.greet() 是成员表达式调用,隐式绑定让 this 指向 object,this.who 读到 "World"。
farewell 是一个箭头函数。箭头函数没有属于自己的 [[ThisMode]]——它在被创建的那一刻,就永久性地捕获了外层词法作用域当时的 this,之后无论怎么调用都不会改变。
这个箭头函数是在脚本顶层创建的,那里的 this 是全局对象,而不是 object。全局对象上没有 who 属性,所以 this.who 读到 undefined,即便 farewell 是以 object.farewell() 的形式被调用,也依然打印 "Goodbye, undefined!"。
这道题考察什么
- 普通方法遵循隐式绑定;箭头函数永远不遵循
- 箭头函数在创建时就以词法方式捕获 this
- object.farewell() 看起来像方法调用,但接收者被完全忽略
运行环境前提
假设运行在经典(非模块)脚本中,顶层 this 是全局对象;在 ES 模块中顶层 this 则是 undefined,此时 this.who 会直接抛出异常。