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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱吃巧克li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值