解密 JavaScript 中的 this:作用、行为和陷阱

简介: JavaScript的this关键字是JavaScript中比较重要的概念之一,本文主要讲解this的作用、行为以及使用它会遇到的陷阱。

前言

JavaScript的this关键字是JavaScript中比较重要的概念之一,本文主要讲解this的作用、行为以及使用它会遇到的陷阱。


作用

this主要用于引用对象,可以通过这个关键字访问对象的属性和方法,可以实现动态操作对象,this在不同的上下文中,有不同的行为,接下来我们就讲解一下this的行为。


行为

它在不同上下文中有不同行为,那么我们举一些经典的场景,


普通函数和全局作用域

在普通函数和全局作用域中this的结果为window对象。

function demo(){
  console.log(this);
}
console.log(this);
demo()



但严格模式下’use strict’,普通函数this指向为undefined也就是未定义的值。


一层作用域链对象与多层作用域链对象

作用域链是什么?

就是指当前变量或属性所在的作用域层级,作用就是可以防止变量出现内存泄漏情况,且保证变量的隐私性和可访问性,确保在函数嵌套中使用正确的变量。


一层作用域链对象指向该对象本身

let person={
  a:'对象属性',
  eat:function(){
    console.log(this.a)
  }
}
person.eat()//对象属性


多层作用链的对象指向的是离的最近的对象。

let person={
  a:'对象属性',
  eat:function(){
    console.log(this.a)
  },
  b:{
    c:'嵌套对象属性',
    drink:function(){
      console.log(this.c);
    }
  }
}
person.eat()//对象属性
person.b.drink()//嵌套对象属性
let Per=person.b.drink
Per()//undefined
let PPer=person.b.drink()
PPer()//嵌套对象属性


为什么Per发起调用时,输出的是undefined呢,因为Per被赋值时,并没有调用该drink函数,指把它的属性方法复制进去了,在调用时,默认调用的还是window对象,而window对象中并没有这个name变量所以输出的就是undefined。

但PPer被赋值的就是drink被调用的方法,所以它的this指向的还是离它最近的那个b对象。


注:本质上,在对象中this 指向默认就是创建该方法的对象。


匿名函数

匿名函数是什么?

匿名函数就是没有名称的函数,它可读性较差且调试困难,但它有一定私密性、可以成为回调函数、闭包、私有作用域(立即执行函数表达式(IIFE))等优点。function(),就是匿名函数。它的this指向是比较复杂的,具体分为以下几种情况。


对象中的匿名函数

指向的是对象

let person={
  b:function(){
    console.log(this);
  }
}
person.b()



全局上下文的匿名函数

指向的是window对象

let a=function(){
  console.log(this);
}
a()//window


使用call、apply、bind改变匿名函数指向

改变成想要的指向对象。在这里插入代码片

var obj = {
  name: 'John'
};
var myFunction = function() {
  console.log(this.name);
};
myFunction.call(obj); // 输出:John
myFunction.apply(obj); // 输出:John
var boundFunction = myFunction.bind(obj);
boundFunction(); // 输出:John




call、apply实际是显式改变了prototype原型,相比之下,bind 方法不会立即执行函数,而是返回一个新的函数,该函数具有预先绑定好的执行上下文。这意味着通过 bind 绑定后的函数可以在稍后的时间点调用,其 this 值将始终保持为绑定时的值。




构造函数

指向的是实例化的新对象。

function drink(){
  this.orange='dudu'
  this.banana='baji'
}
let d=new drink()
console.log(d.orange);//dudu
let e=new drink()
console.log(e.banana);//baji


箭头函数

如果是闭包,上层有非箭头函数,则指向最近的非箭头函数,如果没有,则指向全局对象。



陷阱

在回调函数中,this 的值可能不是我们期望的对象。这是因为回调函数通常在一个不同的上下文中执行,可能会导致 this

指向全局对象或者未定义。为了解决这个问题,可以使用箭头函数或者在调用回调函数之前显式地绑定 this。

使用普通函数作为事件处理程序时,this 的值默认情况下将指向触发事件的元素。但如果使用了箭头函数,则 this

的值将保持为事件绑定时的值,而不会随着事件触发而改变。 在嵌套函数中,this 的值可能会改变。在内部函数中,this

会指向其自己的上下文,而不是外部函数的上下文。要避免这种情况,可以将外部函数的 this 保存到一个变量中,并在内部函数中引用这个变量。


相关文章
|
2月前
|
JavaScript 前端开发
错综复杂的this:理清你的JavaScript代码中的指向问题
错综复杂的this:理清你的JavaScript代码中的指向问题
|
5月前
|
JavaScript 前端开发
详解js中的this指向
详解js中的this指向
37 0
|
5月前
|
前端开发 JavaScript
前端基础 - JavaScript之this关键字
前端基础 - JavaScript之this关键字
21 0
|
1天前
|
JavaScript 前端开发
javascript中的this
javascript中的this
|
4天前
|
JavaScript 前端开发
JavaScript中this的指向问题
JavaScript中this的指向问题
|
5月前
|
前端开发 JavaScript
带你读《现代Javascript高级教程》三、函数上下文和this关键字(1)
带你读《现代Javascript高级教程》三、函数上下文和this关键字(1)
|
5月前
|
JavaScript 前端开发
带你读《现代Javascript高级教程》三、函数上下文和this关键字(2)
带你读《现代Javascript高级教程》三、函数上下文和this关键字(2)
|
2月前
|
前端开发 JavaScript
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(下)
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(下)
|
2月前
|
前端开发 JavaScript
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(上)
揭开`this`的神秘面纱:探索 JavaScript 中的上下文密钥(上)
|
2月前
|
JavaScript 前端开发 API
掌握apply和call,解密JavaScript的this指向
掌握apply和call,解密JavaScript的this指向

相关产品

  • 云迁移中心