解密 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 保存到一个变量中,并在内部函数中引用这个变量。


相关文章
|
6天前
|
JavaScript
Vue.js 修饰符:精准控制组件行为
Vue.js 修饰符:精准控制组件行为
|
6天前
|
JavaScript 前端开发
javascript中的this
javascript中的this
|
6天前
|
JavaScript
JS中改变this指向的六种方法
JS中改变this指向的六种方法
|
4天前
|
前端开发 JavaScript
JavaScript:this-关键字,2024中级前端开发面试解答
JavaScript:this-关键字,2024中级前端开发面试解答
|
6天前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
15 1
|
6天前
|
JavaScript 前端开发
深入探索JavaScript:如何改变this的指向
深入探索JavaScript:如何改变this的指向
|
6天前
|
移动开发 JavaScript 前端开发
javascript监听浏览器离开、进入行为
javascript监听浏览器离开、进入行为
14 0
|
6天前
|
JavaScript 前端开发
【专栏】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表
【4月更文挑战第29天】`Function.prototype.apply` 在JavaScript中用于动态设定函数上下文(`this`)和参数列表。它接受两个参数:上下文对象和参数数组。理解`apply`有助于深入JS运行机制。文章分三部分探讨其原理:基本概念和用法、工作原理详解、实际应用与注意事项。在应用中要注意性能、参数类型和兼容性问题。`apply`可用于动态改变上下文、传递参数数组,甚至模拟其他语言的调用方式。通过深入理解`apply`,能提升代码质量和效率。
|
6天前
|
JavaScript 前端开发 数据安全/隐私保护
|
6天前
|
自然语言处理 JavaScript 前端开发
js_关键字this指向哪里?
js_关键字this指向哪里?
7 0