什么?还没弄懂关键字this?一篇文章带你速通

markdown 复制代码
# JavaScript中`this`关键字的深度解析

`this`是JavaScript中最重要且容易混淆的概念之一,其值取决于**函数调用方式**而非定义位置。以下是全面解析:

## 一、全局上下文中的`this`
在全局执行环境(非严格模式)中,`this`指向全局对象(浏览器中为`window`):
```javascript
console.log(this === window); // true
a = 10;
console.log(this.a); // 10

严格模式 下全局thisundefined

javascript 复制代码
'use strict';
console.log(this); // undefined

二、函数调用中的this

1. 普通函数调用

非严格模式下指向全局对象:

javascript 复制代码
function showThis() {
  console.log(this); // window
}
showThis();

严格模式下为undefined

javascript 复制代码
function strictShow() {
  'use strict';
  console.log(this); // undefined
}

2. 对象方法调用

指向调用该方法的对象:

javascript 复制代码
const user = {
  name: 'Alice',
  greet() {
    console.log(`Hello, ${this.name}!`);
  }
};
user.greet(); // "Hello, Alice!"

3. 构造函数调用

指向新创建的实例:

javascript 复制代码
function Person(name) {
  this.name = name;
}
const bob = new Person('Bob');
console.log(bob.name); // "Bob"

三、显式绑定

通过call()/apply()/bind()强制指定this

javascript 复制代码
function introduce(lang) {
  console.log(`${this.name} codes in ${lang}`);
}

const dev = { name: 'Charlie' };
introduce.call(dev, 'JavaScript'); // "Charlie codes in JavaScript"
const boundFunc = introduce.bind(dev);
boundFunc('Python'); // "Charlie codes in Python"

四、箭头函数的this

继承外层作用域的this(词法作用域):

javascript 复制代码
const timer = {
  delay: 1000,
  start() {
    setTimeout(() => {
      console.log(this.delay); // 正确指向timer对象
    }, this.delay);
  }
};
timer.start();

五、DOM事件处理

指向触发事件的元素:

html 复制代码
<button onclick="console.log(this.tagName)">Click</button>
<!-- 输出 "BUTTON" -->

六、常见问题与解决方案

1. 回调函数丢失this

错误示例:

javascript 复制代码
const counter = {
  count: 0,
  increment() {
    setInterval(function() {
      this.count++; // this指向window!
    }, 1000);
  }
};

解决方案:

javascript 复制代码
// 方案1:箭头函数
setInterval(() => this.count++, 1000);

// 方案2:bind绑定
setInterval(function() {
  this.count++;
}.bind(this), 1000);

// 方案3:保存this引用
const self = this;
setInterval(function() {
  self.count++;
}, 1000);

2. 方法赋值导致this丢失

javascript 复制代码
const obj = {
  id: 'obj1',
  logId() { console.log(this.id) }
};
const fn = obj.logId;
fn(); // undefined(this指向全局)

总结表格

场景 this指向 示例
全局环境 全局对象(非严格模式) this === window
普通函数调用 全局对象/undefined function() { console.log(this) }()
对象方法调用 调用对象 obj.method()
构造函数 新创建的实例 new Constructor()
箭头函数 外层作用域的this () => { console.log(this) }
事件处理器 触发事件的DOM元素 elem.onclick = function() { console.log(this) }
显式绑定 绑定的对象 func.call(ctx)

理解this的关键在于分析函数的调用方式,而非定义位置。

相关推荐
coding随想1 小时前
JavaScript ES6 解构:优雅提取数据的艺术
前端·javascript·es6
年老体衰按不动键盘1 小时前
快速部署和启动Vue3项目
java·javascript·vue
小小小小宇1 小时前
一个小小的柯里化函数
前端
灵感__idea1 小时前
JavaScript高级程序设计(第5版):无处不在的集合
前端·javascript·程序员
小小小小宇2 小时前
前端双Token机制无感刷新
前端
小小小小宇2 小时前
重提React闭包陷阱
前端
小小小小宇2 小时前
前端XSS和CSRF以及CSP
前端
UFIT2 小时前
NoSQL之redis哨兵
java·前端·算法
超级土豆粉2 小时前
CSS3 的特性
前端·css·css3
星辰引路-Lefan2 小时前
深入理解React Hooks的原理与实践
前端·javascript·react.js