You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ES6箭头函数与传统函数的this指向及作用域差异疑问

核心知识点误区澄清

你混淆了「普通变量的词法作用域查找规则」和「普通函数this的绑定规则」,二者是完全独立的两套逻辑:

  • 普通变量的查找确实遵循词法作用域,按声明位置的嵌套关系从内到外查找
  • 普通函数的this是动态绑定,和声明位置完全无关,仅由函数被调用的方式决定

普通函数this的4种绑定规则

普通函数的this绑定优先级从高到低如下:

  1. new绑定:函数被new调用时,this绑定到新创建的实例对象
  2. 显式绑定:通过call/apply/bind手动指定this时,this绑定到传入的对象
  3. 隐式绑定:函数作为对象的方法被调用时(形如obj.func()),this绑定到前面的对象obj
  4. 默认绑定:以上三种都不满足的「独立函数调用」场景,非严格模式下this绑定到全局对象(浏览器环境为window,Node环境为globalThis),严格模式下为undefined

针对你给出的示例逐一解释

示例3的问题根源

你示例中的namedFn()就是典型的独立调用,没有前缀对象、没有手动指定this、也不是new调用,直接触发默认绑定,非严格模式下this就是window。而全局window上没有定义count属性,所以this.count输出undefined。
哪怕namedFn声明在doSomethingLater内部,也不会影响this的绑定结果,因为普通函数this和声明位置无关。

MDN传统函数示例的问题根源

setTimeout传入的普通函数回调,在执行时是JS引擎独立调用的,同样触发默认绑定,this指向window。初始时window.count为undefined,执行this.count++后结果为NaN,和示例3本质是同一个原因。

箭头函数的特殊规则

箭头函数不存在自己的this,它的this完全遵循词法作用域规则,继承自外层作用域的this,所以才会出现你看到的和普通函数完全不同的表现。

简单修改方案

如果想让示例3中namedFn的this指向外层的obj,可以用以下任意一种方式修改:

  • 用bind显式绑定this:namedFn.bind(this)()(doSomethingLater是作为obj的方法调用的,内部this指向obj)
  • 把namedFn改成箭头函数:const namedFn = () => {console.log(this.count)},继承外层作用域的this
  • 调用时用call显式传入this:namedFn.call(this)

内容的提问来源于stack exchange,提问作者Angela P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 11:15:02