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


相关文章
|
1月前
|
监控 JavaScript 前端开发
使用Vue.js开发员工上网行为监控的实时数据展示页面
使用Vue.js开发的实时员工上网行为监控页面,展示员工访问的网站、应用和时间等数据。页面响应式设计,适应不同设备。通过Vue组件显示实时数据,如`<li v-for="activity in activities">`循环渲染。数据定时更新,利用Vue的生命周期钩子和axios从服务器获取并自动刷新,确保数据的时效性。该页面有助于管理者即时了解员工网络活动,保障企业网络安全和资源管理。
124 5
|
18天前
|
JavaScript 前端开发 开发者
JavaScript的变量提升是一种编译阶段的行为,它将`var`声明的变量和函数声明移至作用域顶部。
【6月更文挑战第27天】JavaScript的变量提升是一种编译阶段的行为,它将`var`声明的变量和函数声明移至作用域顶部。变量默认值为`undefined`,函数则整体提升。`let`和`const`不在提升范围内,存在暂时性死区。现代实践推荐明确声明位置以减少误解。
20 2
|
1月前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【6月更文挑战第15天】JavaScript的`this`根据调用方式变化:非严格模式下直接调用时指向全局对象(浏览器为window),严格模式下为undefined。作为对象方法时,`this`指对象本身。用`new`调用构造函数时,`this`指新实例。`call`,`apply`,`bind`可显式设定`this`值。箭头函数和绑定方法有助于管理复杂场景中的`this`行为。
42 3
|
11天前
|
JavaScript
js 【详解】函数中的 this 指向
js 【详解】函数中的 this 指向
12 0
|
12天前
|
JavaScript 前端开发
|
20天前
|
JavaScript
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......
js -- 函数总结篇,函数提升、动态参数、剩余参数、箭头函数、this指向......
|
2月前
|
JavaScript 前端开发
js中改变this指向、动态指定函数 this 值的方法
js中改变this指向、动态指定函数 this 值的方法
|
27天前
|
JavaScript 前端开发
JS中如何使用this方法
JS中如何使用this方法
|
2月前
|
自然语言处理 JavaScript 前端开发
在JavaScript中,this关键字的行为可能会因函数的调用方式而异
【5月更文挑战第9天】JavaScript中的`this`关键字行为取决于函数调用方式。在非严格模式下,直接调用函数时`this`指全局对象,严格模式下为`undefined`。作为对象方法调用时,`this`指向该对象。用`new`调用构造函数时,`this`指向新实例。通过`call`、`apply`、`bind`可手动设置`this`值。在回调和事件处理中,`this`可能不直观,箭头函数和绑定方法可帮助管理`this`的行为。
25 1
|
2月前
|
JavaScript 前端开发
深入探索JavaScript:如何改变this的指向
深入探索JavaScript:如何改变this的指向
15 2