题目 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 会直接抛出异常。

规范参考

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

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