什么?还没弄懂关键字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的关键在于分析函数的调用方式,而非定义位置。

相关推荐
JNU freshman14 分钟前
vue 之 import 的语法
前端·javascript·vue.js
剑亦未配妥15 分钟前
Vue 2 响应式系统常见问题与解决方案(包含_demo以下划线开头命名的变量导致响应式丢失问题)
前端·javascript·vue.js
爱吃的强哥18 分钟前
Vue2 封装二维码弹窗组件
javascript·vue.js
凉柚ˇ18 分钟前
Vue图片压缩方案
前端·javascript·vue.js
慧一居士18 分钟前
vue 中 directive 作用,使用场景和使用示例
前端
慧一居士20 分钟前
vue 中 file-saver 功能介绍,使用场景,使用示例
前端
ByteCraze33 分钟前
秋招被问到的常见问题
开发语言·javascript·原型模式
渣哥1 小时前
从代理到切面:Spring AOP 的本质与应用场景解析
javascript·后端·面试
文心快码BaiduComate1 小时前
文心快码3.5S实测插件开发,Architect模式令人惊艳
前端·后端·架构
UIUV1 小时前
JavaScript代理模式实战解析:从对象字面量到情感传递的优雅设计
javascript