JavaScript 箭头函数中 this 指向机制解析
本文深入解析 JavaScript 中箭头函数的 this 指向机制。与普通函数不同,箭头函数不创建自己的 this 上下文,而是继承自外层作用域。文章通过代码示例对比了箭头函数与普通函数在隐式绑定、默认绑定等场景下的行为差异,并解释了为何 call/apply 无法改变箭头函数的 this 指向,帮助开发者准确掌握 ES6 函数特性。
箭头函数 this 继承机制
箭头函数自身不生成独立的 this 值,而是依据其定义时的词法作用域链,从外层执行上下文中继承 this 绑定。
由于箭头函数内部不存在自身的 this 指针,若尝试使用 call() 或 apply() 方法调用该函数,仅能传递额外参数,无法实现 this 的重新绑定,且传入的第一个参数(通常用于指定 this)将被忽略。
前置阅读建议
前言
在深入探讨前,建议参考《你不知道的 JavaScript(上)》第二部分关于 this 和对象原型的论述,该章节对 this 指向的理论基础有详细阐述。
常见误区与验证
问题
本周编码过程中,同事提出箭头函数无法改变 this 指向的观点,并通过以下代码片段进行了验证:
// (1) 使用箭头函数,this一直指向window
var a = 0
var obj1 = {
a: 1,
fn: () => { console.log(this.a) }
}
obj1.fn() // 结果:0
var obj2 = {
a: 2
}
obj2.fn = obj1.fn
obj2.fn() // 结果:0
// (2)不使用箭头函数,this的指向会更改
var obj3 = {
a: 3,
fn: function() { console.log(this.a) }
}
obj3.fn() // 结果:3
观察第一段代码可知,无论将 fn 方法绑定至哪个对象,this.a 始终指向全局变量 a(在非严格模式的浏览器环境中,这通常对应 window 对象)。
然而,我认为这种观点存在片面性。
this 指向的核心原理
先理解 this
this 的具体指向取决于以下因素:
- 调用位置
- 四种绑定规则
var a = 0
test() // 调用位置在此,通过【默认绑定规则】,可知test的this绑定到了window上
function test() {
console.log(this) // this是window
var obj1 = {
a: 1,
fn: function() {
console.log(this) // this是obj1
console.log(this.a)
}
}
obj1.fn() // 调用位置在此,通过【隐式绑定规则】,可知fn中的this绑定到了obj1上
var obj2 = {
a: 2
}
obj2.fn = obj1.fn
obj2.fn() // 调用位置在此,【隐式绑定规则】,可知fn内的this绑定到了obj2
}
箭头函数 this 来源解析
箭头函数中的this
使用此标题可能不够严谨(因尚未想出更贴切的名称),但根据 MDN 文档,箭头函数确实不会创建自己的 this 上下文。那么,下述代码中的 this 究竟源自何处?
var obj3 = {
a: 3,
fn: () => {
console.log(this.a)
}
}
obj3.fn() // 调用位置在此,this指向window
arrowFoo1() // (1)此处是调用位置,使用【默认的绑定规则】,this = window
function arrowFoo1() {
var obj1 = {
vv: 'svv1',
fn: () => {
console.log(this.vv, 'vv的值是')
}
}
// (2)调用位置是此处,若fn不是箭头函数,那么这里也会有自己的this(即【隐式调用规则】,this绑定为obj1),而fn是箭头函数,则它没有this,那么fn内部调用的this是谁?
// 这时候需要根据作用域的规则,往外层查找,找到哪里?找到调用obj1.fn的调用栈,即arrowFoo1函数的this,那么从(1)中可知,那个this指向的是window
obj1.fn()
var obj2 = {
vv: 'svv2',
}
obj2.fn = obj1.fn
obj2.fn()
}
function arrowFoo2() {
var vv = '哦哦哦哦哦'
console.log(this.vv, 'vv的值是')
}
因此,当箭头函数内部引用 this 时,它实际上是通过作用域链向外层查找,直至找到绑定的 this 并直接返回。
总结
以上就是本文的全部内容,希望这些内容对您的学习或工作有所参考,感谢支持。
JavaScript怎么准确判断数据类型:typeof、instanceof与Object.prototype.toString
2026-11-05 17:09:21
JS中将数组和对象混合组装为JSON字符串
2026-11-05 16:41:42
JS运算符优先级与结合性的区别是什么?
2026-11-05 13:22:02
JS Map怎么只遍历Key或Value
2026-11-05 13:00:36
D3.js 与 ECharts 选型对比:灵活性 vs 开发效率
2026-11-05 09:45:01
