今天,彻底搞懂 JS 中的 this !

Photo by Vadim Bogulov on Unsplash

前端开发这么久,还是不懂 this ? 今天,彻底搞懂!

JavaScript 中的 this 是一个动态绑定的关键字,它的值由 函数调用方式执行上下文 共同决定。下面我会通过分类、示例和核心规则,帮助你彻底理解 this 的各种场景。


一、核心规则:this 的绑定机制

this 的值在函数被调用时确定,而非定义时。以下是 this 的 5 种绑定规则:

规则 场景示例 this 指向 优先级
默认绑定 独立函数调用 全局对象(严格模式为 undefined 最低
隐式绑定 作为对象方法调用 调用该方法的对象
显式绑定 使用 call/apply/bind 手动指定的对象
new 绑定 构造函数调用 新创建的实例对象 最高
箭头函数 箭头函数 外层作用域的 this(词法绑定) 不适用

二、普通函数中的 this

1. 默认绑定(独立调用)

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

showThis(); // 浏览器中输出 window(非严格模式)
            // 严格模式("use strict")下输出 undefined

2. 隐式绑定(作为对象方法调用)

javascript 复制代码
const obj = {
  name: "Alice",
  sayName() {
    console.log(this.name); // this 指向 obj
  },
};

obj.sayName(); // "Alice"

3. 隐式丢失问题

当方法被赋值给变量或作为回调时,this 可能丢失:

javascript 复制代码
const say = obj.sayName;
say(); // 输出 undefined(this 指向全局对象)

setTimeout(obj.sayName, 100); // 输出 undefined(this 指向全局对象)

三、箭头函数中的 this

箭头函数 没有自己的 this ,它会 继承外层作用域(定义时的上下文)的 this

1. 基本示例

javascript 复制代码
const obj = {
  name: "Bob",
  sayName: () => {
    console.log(this.name); // this 继承外层作用域(此处为全局对象)
  },
};

obj.sayName(); // 输出 undefined(浏览器中全局 name 不存在)

2. 在普通函数内部的箭头函数

javascript 复制代码
function outer() {
  const innerArrow = () => {
    console.log(this); // 继承 outer 的 this
  };
  innerArrow();
}

outer.call({ name: "Alice" }); // 输出 { name: "Alice" }
outer(); // this 指向全局对象

const obj = {
  name: 'will',
  test: outer
}

obj.test(); // this 指向 obj

四、显式绑定:call/apply/bind

手动指定 this 的值:

javascript 复制代码
function greet() {
  console.log(`Hello, ${this.name}`);
}

const alice = { name: "Alice" };
const bob = { name: "Bob" };

// 临时绑定
greet.call(alice);    // "Hello, Alice"
greet.apply(bob);     // "Hello, Bob"

// 永久绑定(返回新函数)
const greetAlice = greet.bind(alice);
greetAlice();         // "Hello, Alice"

五、构造函数中的 this

通过 new 调用构造函数时,this 指向新创建的实例:

javascript 复制代码
function Person(name) {
  this.name = name;
}

const alice = new Person("Alice");
console.log(alice.name); // "Alice"

六、事件监听器中的 this

在 DOM 事件处理函数中,this 指向触发事件的元素:

javascript 复制代码
document.querySelector("button").addEventListener("click", function() {
  console.log(this); // 输出按钮元素
});

七、严格模式下的 this

严格模式("use strict")下,独立调用的函数 thisundefined

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

八、嵌套函数中的 this

1. 普通函数嵌套

javascript 复制代码
const obj = {
  name: "Alice",
  outer() {
    function inner() {
      console.log(this); // 默认绑定,指向全局对象
    }
    inner();
  },
};

obj.outer(); // 输出 window(非严格模式)

2. 箭头函数嵌套解决 this 丢失

javascript 复制代码
const obj = {
  name: "Alice",
  outer() {
    const inner = () => {
      console.log(this); // 继承 outer 的 this(指向 obj)
    };
    inner();
  },
};

obj.outer(); // 输出 obj

九、总结:this 的决策流程图

javascript 复制代码
判断函数类型 → 是否是箭头函数?
  ├─ 是 → 继承外层作用域的 `this`
  └─ 否 → 判断调用方式:
           ├─ new 调用 → 指向新实例
           ├─ call/apply/bind → 指向指定对象
           ├─ 对象方法调用 → 指向该对象
           └─ 独立调用 → 严格模式为 undefined,否则全局对象

十、常见误区与解决方案

  1. 回调函数中的 this 丢失

    使用箭头函数或显式绑定:

    javascript 复制代码
    setTimeout(() => obj.sayName(), 100); // 箭头函数继承外层 this
    setTimeout(obj.sayName.bind(obj), 100); // 显式绑定
  2. 对象方法赋值后 this 丢失

    使用箭头函数或在构造函数中绑定:

    javascript 复制代码
    class MyClass {
      constructor() {
        this.method = this.method.bind(this);
      }
      method() { /* ... */ }
    }

通过以上分类和示例,你应该能全面掌握 JavaScript 中 this 的行为规律。记住:this 的值由调用方式决定,箭头函数是唯一的例外(词法绑定)

相关推荐
专注API从业者4 小时前
Python + 淘宝 API 开发:自动化采集商品数据的完整流程
大数据·运维·前端·数据挖掘·自动化
你的人类朋友5 小时前
【Node&Vue】JS是编译型语言还是解释型语言?
javascript·node.js·编程语言
烛阴5 小时前
TypeScript高手密技:解密类型断言、非空断言与 `const` 断言
前端·javascript·typescript
样子20186 小时前
Uniapp 之renderjs解决swiper+多个video卡顿问题
前端·javascript·css·uni-app·html
Nicholas686 小时前
flutterAppBar之SystemUiOverlayStyle源码解析(一)
前端
黑客飓风6 小时前
JavaScript 性能优化实战大纲
前端·javascript·性能优化
emojiwoo8 小时前
【前端基础知识系列六】React 项目基本框架及常见文件夹作用总结(图文版)
前端·react.js·前端框架
张人玉8 小时前
XML 序列化与操作详解笔记
xml·前端·笔记
杨荧8 小时前
基于Python的宠物服务管理系统 Python+Django+Vue.js
大数据·前端·vue.js·爬虫·python·信息可视化
YeeWang9 小时前
🎉 Eficy 让你的 Cherry Studio 直接生成可预览的 React 页面
前端·javascript