深入理解 JavaScript 中的 this 关键字

this关键字

前言

在 JavaScript 中,this 是一个核心概念,但它也是最容易让人困惑的部分之一。理解 this 的机制对于编写健壮、可维护的代码至关重要。this 的值取决于函数如何被调用 ,而不是在哪里定义。以下让我们来了解一下this关键字,并通过实例来了解。

为什么要有this

this是一个代词,指代一个对象

this 提供了一直更优雅的方式来隐式的传递一个对象的引用,可以让代码更加简洁易于复用

this 可以用在哪里

1、函数作用域

2、全局作用域(this指向window)

this的绑定规则

1、默认绑定 ---- 当函数被独立调用时,函数的this指向window

2、隐式绑定 ---- 当函数引用有上下文对象,且被该对象调用时,隐式绑定规则会把函数调用中的this绑定到这个上下文对象

3、隐式丢失 ---- 当一个函数被多层对象调用时,函数的 this 指向最近的那一层对象

4、new绑定 ---- const p1 = new Foo() ----> new的原理会导致函数的 this 指向的是实例对象

5、显示绑定

1、{fn.call(obj,x,y,...)显示将 fn 里面的 this 绑定到 obj 上,call 负责帮 fn 接收参数}

2、{fn.apply(obj,[x,y,...])显示的将 fn 里面的 this 绑定到 obj 上,apply 负责帮 fn 接受参数,参数必须以数据组形式存放}

3、{fn.bind(obj,x,y,...)(x,y,...)显示的将 fn 里面的 this 绑定到 obj 上,bind会返回一个新的函数,bind和新函数都可以负责帮 fn 接受参数,参数零散的传入,优先传(obj,x,y...)里面的}

注意:箭头函数中没有 this 这个概念,写在了箭头函数中的 this,也是它外层那个非箭头函数的 this

快速寻找this代指的值

1、先判断有没有箭头函数,如果有要先判断箭头函数里面的 this 指向谁

2、再判断是否含有call、apply、bind方法

3、再找有没有new

4、最后找函数是否被调用,若被调用怎么考虑隐式绑定,若独立调用则是默认绑定

注意:隐式绑定必须要被引用同时还要被对象调用才会进入隐式绑定,若二者缺一那么就不是隐式绑定

实例实践

判断以下代码的输出值

1、

js 复制代码
var a = 1
function foo(){
  console.log(this.a);
}
function bar(){
  var a = 2
  foo()
}
bar()

答案 : 1

原因 : 直接调用foo,属于默认绑定,this指向的是全局

2、

js 复制代码
var a = 3
function foo() {
  var a = 2
  function bar() {
    var a = 1
    console.log(this.a);
  }
  bar()
}
foo()

答案 : 3

原因 : 直接调用bar,属于默认绑定,this指向的是全局

3、

js 复制代码
var a = 1
function foo() {
  console.log(this.a);
}
var obj = {
  a : 2,
  foo: foo
}
obj.foo()

答案 : 2

原因 : obj引用了foo方法,并且用obj.foo调用了,属于隐式绑定,指向obj函数

4、

js 复制代码
var a = 1
function foo() {
  console.log(this.a);
}
var obj = {
  a : 2,
  foo: foo
}
var obj2 = {
  a: 3,
  foo: obj
}
obj2.foo.foo()

答案 : 2

原因 : obj引用了foo方法,并且用obj.foo调用了,属于隐式绑定,指向obj函数,但是obj2引用了obj方法,同时也调用了,属于隐式绑定,那么现在出现了隐式丢失这种情况,这时候this指向最近的那个函数即obj

5、

js 复制代码
function foo(x, y) {
  console.log(this.a, x + y);
}
var obj = {
  a: 1
}
foo.call(obj, 1, 2)

答案 : 1

原因 : 使用了call方法调用函数,属于显示绑定,this指向()里面的函数

6、

js 复制代码
function Person() {
  // var obj = {}
  // Person.call(obj)
  this.name = 'Z'
  this.age = 18
  console.log(this.name,this.age);
  // obj._ _proto_ _ = Person.prototype
  // return obj
}
const p1 = new Person()

答案 : Z,18

原因 : 用new创建了一个实例对象,属于new绑定,this指向实例对象

7、

js 复制代码
var a = 1
var obj = {
  a: 2,
  bar: function () {
    const baz = () => {
      console.log(this.a);
    }
    baz()
  }
}
obj.bar()

答案 : 2

原因 : 使用了箭头函数,所以这里的this是属于bar()函数里面的,又因为在obj里面引用了bar函数,并且调用了obj函数,属于隐式绑定,this指向obj

最后

​🚀 掌握 this,让你的 JavaScript 代码更精准、更强大!​

this 虽然容易让人困惑,但一旦理解它的运行机制,你就能:

✅ ​​写出更健壮、可维护的代码​

✅ ​​避免常见的 undefined 和上下文丢失问题​

✅ ​​在 React、Vue 等框架中更自如地控制组件状态​

​现在就开始练习吧!​ ​ 试着分析不同场景下的 this 指向,并在项目中灵活运用 callapplybind 和箭头函数,让你的代码更加优雅高效!

​💡 记住:​

​"this 不是魔法,而是规则。"​​ ------ 掌握规则,你就是 JavaScript 高手!

Happy Coding! 🎯🚀

相关推荐
可乐只喝可乐6 分钟前
从0到1构建一个Agent智能体
前端·typescript·agent
Muxxi13 分钟前
shopify模板开发
前端
Yueyanc13 分钟前
LobeHub桌面应用的IPC通信方案解析
前端·javascript
我是若尘28 分钟前
利用资源提示关键词优化网页加载速度
前端
moyu8431 分钟前
跨域问题解析(下):Nginx代理、domain修改与postMessage解决方案
前端
moyu841 小时前
跨域问题解析(上):JSONP、CORS与Node代理解决方案
前端
moyu841 小时前
深入理解TCP的三次握手与四次挥手
前端
不一样的少年_1 小时前
头像组件崩溃、乱序、加载失败?一套队列机制+多级兜底全搞定
前端·vue.js
Code_XYZ1 小时前
uni-app x开发跨端应用,与web-view的双向通信解决方案
前端
wordbaby1 小时前
构建时规划,运行时执行:解构 React Router 的 prerender 与 loader
前端·react.js