this 是 JavaScript 中最容易让人困惑的概念之一。它的指向取决于函数的调用方式而非定义位置,且在不同场景下表现不同。
一、this 的本质
this 是一个动态绑定的执行上下文对象,指向当前函数运行时的“所有者”。它的值在函数被调用时确定,而非定义时。理解 this 的关键在于分析函数是如何被调用的。
二、绑定规则
1. 默认绑定(独立函数调用)
当函数作为独立函数调用时(非方法、构造函数等),非严格模式下 this 指向全局对象(浏览器中为 window),严格模式下为 undefined。
function showThis() {console.log(this);}showThis(); // 浏览器环境输出 window(非严格模式)// 严格模式输出 undefined
2. 隐式绑定(方法调用)
当函数作为对象方法调用时,this 指向调用该方法的对象。
⚠️ 隐式丢失陷阱:方法被赋值给变量后调用会导致 this 丢失。const obj = {name: 'Object',logThis() {console.log(this.name);}};obj.logThis(); // 输出 "Object"
const temp = obj.logThis;temp(); // 输出 undefined(非严格模式指向 window)
3. 显式绑定(call/apply/bind)
通过 call(), apply() 或 bind() 强制指定 this 值。
function greet() {console.log(`Hello, ${this.name}`);}const user = { name: 'Alice' };greet.call(user); // 输出 "Hello, Alice"const boundGreet = greet.bind(user);boundGreet();
4. new 绑定(构造函数)
使用 new 调用构造函数时,this 指向新创建的实例对象。
function Person(name) {this.name = name;}const bob = new Person('Bob');console.log(bob.name); // 输出 "Bob"
5. 箭头函数
箭头函数没有自己的 this,继承外层作用域的 this 值,且无法通过 call/apply 修改。
const obj = {traditional: function() {console.log(this); // 指向 obj},arrow: () => {console.log(this); // 继承外层(此处为全局)}};obj.traditional(); // objobj.arrow(); // window(非严格模式)
三、优先级规则
当多个规则同时适用时,按以下优先级决定 this 指向:
new 绑定 > 显式绑定 > 隐式绑定 > 默认绑定
四、this的3个特殊使用场景
1. 回调函数中的 this
常见于定时器、事件监听等场景,需要特别注意 this 指向:
const button = document.querySelector('button');button.addEventListener('click', function() {console.log(this); // 指向 button 元素});// 使用箭头函数时:button.addEventListener('click', () => {console.log(this); // 继承外层 this(可能是 window)});
2. 嵌套函数中的 this
内部函数不会继承外部函数的 this(除非使用箭头函数)
const obj = {name: 'Obj',outer() {function inner() {console.log(this); // 默认绑定,非严格模式指向 window}inner();}};
3. 类中的 this
类方法中的 this 指向实例对象,但需注意方法作为回调时的绑定问题:
class Counter {constructor() {this.count = 0;// 需要绑定或使用箭头函数this.increment = this.increment.bind(this);}increment() {this.count++;}}
五.this的4个实用小技巧
-
1.明确绑定:在需要固定 this 指向时,优先使用箭头函数或 bind
-
2.避免混用:同一函数中不要同时使用普通函数和箭头函数定义方法
-
3.严格模式:使用
'use strict'避免意外指向全局对象 -
4.调试技巧:在复杂场景中使用
console.log(this)快速定位当前值
六、总结
| 调用方式 | this 指向 | 示例 |
|---|---|---|
| 直接调用 | 全局对象/undefined | func() |
| 方法调用 | 调用对象 | obj.method() |
| new 调用 | 新创建的实例 | new Constructor() |
| call/apply/bind | 指定的对象 | func.call(ctx) |
| 箭头函数 | 外层作用域的 this | () => {...} |
理解 this 的关键在于分析函数的调用位置和调用方式。通过掌握绑定规则和优先级,可以准确预测代码行为,避免常见陷阱。
![]() |
Austin Liu 刘恒辉
Project Manager and Software Designer E-Mail:lzhdim@163.com Blog:https://lzhdim.cnblogs.com 欢迎收藏和转载此博客中的博文,但是请注明出处,给笔者一个与大家交流的空间。谢谢大家。 |




浙公网安备 33010602011771号