百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 行业知识 > 正文

JavaScript中this 关键字是什么呢?

citgpt 2024-11-25 10:01 5 浏览 0 评论

ES6以来,大量加入的新语法极大地方便了我们编程的同时,也增加了很多我们理解的心智负担。要想认识这些函数的执行上下文切换,我们必须要对他们行为上的区别有所了解。

对普通变量而言,这些函数并没有本质区别,都是遵循了'继承定义时的环境'的规则,它们的一个行为差异在于this关键字。

JavaScript中this 关键字是什么呢?

那么,this 关键字是什么呢?

this 关键字行为

this 是JavaScript中的一个关键字,它的使用方法类似一个变量(但是this跟变量有很多不同)。

this是执行上下文中很重要的一个组成部分。同一个函数调用方式不同,得到的this值也不同,我们看一个例子:

function showThis(){
console.info(this)
}

var o = {
showThis: showThis
}

showThis(); //global
o.showThis(); //o
在这个例子中,我们定义了函数showThis,我们把它赋值给了一个对象o的属性,然后尝试分别使用两个引用来调用同一个函数,结果得到了不同的this值。

普通函数的 this 值由'调用它所使用的的引用'来决定,其中奥秘就在于:我们获取函数的表达式,它实际上返回的并非函数本身,而是一个 Reference 类型(其中标准类型之一)。

Reference 类型由两部分组成,一个对象和一个属性值。不难理解 o.showThis 产生的Reference类型,即由对象 o 和属性'showThis'构成。

当做一些算术运算时,Reference类型会被解引用,即获取真正的值来参与运算,而类似函数调用,delete等操作,都需要用到 Reference 类型中的对象。

在这个例子中,Reference类型中的对象被当做this值,传入了执行函数的上下文中。

至此,我们对this的解释已经非常清晰了,调用函数时使用的引用,决定了函数执行时刻的this值。

实际上从运行时的角度来看,this跟面向对象毫无关联,它是与函数调用的表达式相关。

这个设计来自JavaScript早年,通过这样的方式,巧妙地模拟了Java的语法,但是仍然保留了纯粹的'无类'运行时设施。

如果,我们把这个例子稍作修改,换成箭头函数,结果就不一样了。

const showThis = () => {
console.log(this);
}

var o = {
showThis: showThis
}

showThis(); // global
o.showThis(); // global
我们看到,改为箭头函数后,无论用什么来调用它,都不影响它的this值。

接下来我们看看'方法',它的行为又不一样了:

class C {
showThis() {
console.log(this);
}
}
var o = new C();
var showThis = o.showThis;

showThis(); // undefined
o.showThis(); // o
这里我们创建了一个类C,并且实例化出对象o,再把 o 的方法赋值给了变量 showThis。

这时候,我们使用 showThis 这个引用去调用方法时,得到了undefined。

所以,在方法中,我们看到this的行为也不大一样,它得到了undefined的结果。

按照我们上面的方法,不难验证出:生成器函数,异步函数和异步普通函数跟普通函数行为是一致的,异步箭头函数与箭头函数的行为是一致的。

this关键字机制

说完了this行为,我们再来简单谈谈在JavaScript内部,实现this这些行为的机制。

函数能够引用定义时的变量,如上文分析,函数能记住定义时的this,因此,函数内部必须有一个机制来保存这些信息。

在JavaScript标准中,为函数规定了用来保存定义是上下文的私有属性[[Environment]]。

当一个函数执行时,会创建一条新的执行环境记录,记录的外层词法环境(outer lexical environment)会被设置成函数的[[Environment]]。

这个动作就是切换上下文了,我们假设有这样的代码:

var a = 1;
foo();
在别处定义了foo:

var b = 2;
function foo(){
console.log(b); // 2
console.log(a); // error
}
这里的foo能够访问 b (定义时的词法环境),却不能访问 a (执行时的词法环境),这就是执行上下文的切换机制了。

JavaScript用一个栈来管理执行上下文,这个栈的每一项又包含一个链表。如下图所示:


当函数调用时,会入栈一个新的执行上下文,函数调用结束时,执行上下文被出栈。

而this则是一个更为复杂的机制,JavaScript标准定义了[[thisMode]]私有属性。

[[thisMode]]私有属性有三个取值

lexical:表示从上下文中找this,这对应了箭头函数。
global:表示this为undefined时,取全局对象,对应了普通函数。
strict:当严格模式时使用,this严格按照调用时传入的值,可能为null或者undefined。
非常有意思的是,方法的行为跟普通函数有差异,恰恰是因为class设计成了默认按照strict模式执行。

我们可以用strict达成与上一节中方法的例子中一样的效果。

"use strict"
function showThis(){
console.log(this);
}

var o = {
showThis: showThis
}

showThis(); // undefined
o.showThis(); // o
函数创建新的执行上下文中词法环境记录时,会根据[[thisMode]]来标记新纪录的[[ThisBindingStatus]]私有属性。

代码执行遇到this时,会组成检查当前词法环境记录中的[[ThisBindingStatus]],当我们找到有this的环境记录时获取this的值。

这样的规则的实际效果时,嵌套的箭头函数中的代码都指向外层this,例如:

var o = {}
o.foo = function foo(){
console.log(this);
return () => {
console.log(this);
return () => console.log(this);
}
}

o.foo()()(); // o, o, o
在上面的例子中,我们定义了三层嵌套的函数,最外层的是普通函数,两层都是箭头函数。

这里调用三个函数,获得的this值是一样的,对象都是o。

JavaScript还提供了一系列函数的内置方法来操作this值,下面我们来了解一下。

操作this的内置函数

Function.prototype.call和Function.prototype.apply可以执行函数调用时传入的this值,示例如下:

function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.call({}, 1, 2, 3);
foo.apply({}, [1, 2, 3]);
这里call和apply作用是一样的,只是传参方式有区别。

此外,还有Function.prototype.bind 它可以生成一个绑定的函数,这个函数的this值固定了参数。

function foo(a, b, c){
console.log(this);
console.log(a, b, c);
}
foo.bind({}, 1, 2, 3)();
有趣的是,call,bind和apply用于不接受this的函数类型如箭头,class都不会报错。

这时候,它们无法实现改变this的能力,但是可以实现传参。
————————————————
版权声明:本文为CSDN博主「ECUSTJared」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_30391353/article/details/112104821

相关推荐

外贸网站建设要多少钱?外贸网站建设周期要多久

大家好,我是【无锡柠萌网络lemon56.com】的小美,今天分享:外贸网站建设要多少钱?外贸网站建设周期要多久您关注的问题·FAQ外贸网站建设中遇到的常见问题,让您少走弯路,提高效率!...

500块搭建一个可以卖货的跨境电商独立站,包括服务器和域名吗?

用500元搭建一个可以卖货的跨境电商独立站,虽然有一定挑战性,但通过精打细算和选择合适的工具和服务,仍然是有可能的。以下是一些建议,帮助你在预算范围内实现这个目标,包括服务器和域名的选择。...

无锡网络公司设计搭建阀门网站一般要多少钱?

无锡网络公司设计搭建阀门网站一般要多少钱?这是一个涉及多方面因素的复杂问题,其费用因网站规模、功能需求、设计复杂度及后续维护等因素而异。首先,从基础成本出发,域名注册是搭建网站的第一步,费用通常在几十...

定制化网站开发大概多少钱

定制化网站开发的价格因项目的复杂性、功能需求、设计要求和开发时间等因素而异。以下是一些常见的定制化网站开发价格范围,供参考:1.简单的定制化网站开发:一般来说,一个简单的定制化网站开发项目可能需要花...

9月安卓手机性能排行榜出炉:前十名差距仅为7%

时间已经进入9月,按照安兔兔目前的安卓手机性能榜单显示,红魔9SPro+依旧力压其他热销手机成为榜首,可见游戏定位的这款手机,在性能上确实非常的出色。不过,笔者也发现了一个问题,其中前十名中得分最高...

装修公司怎么在网络平台接单?实现高效获客

装修行业正经历着深刻的变革,随着消费者需求的日益多样化与个性化,传统的线下获客方式已难以满足装修公司的业务需求。因此,装修公司必须紧跟时代步伐,充分利用网络平台实现高效获客。1、入驻装修接单平台:壹品...

企业如何利用二维码进行线上营销?

#企业如何利用二维码进行线上营销?#企业利用二维码进行线上营销,可以从以下几个方面入手:?1.设计创意二维码?:...

家电销售该怎么线上拓客

社交媒体平台:利用微信、微博、抖音等平台,定期发布家电产品的信息、使用心得、促销活动等内容。引流靠手动一定是不行的,所以一般使用点软件肯定没错,最近用了款比较冷门的APP,"里德助手Plus...

pop社交软件,脱单软件排行榜

在交友软件里面脱单是非常明确的一件事,各年龄各社交平台上的女人都是有所不同的,具体问题具体分析一下。接下来就说说又哪些比较优质的恋爱脱单软件。...

手机处理器最新跑分排行榜,你的手机什么水平?

手机处理器最新跑分排行榜,你的手机什么水平?第1名:天玑9300第2名:骁龙8Gen3第3名:A17Pro第4名:天玑9200第5名:骁龙8Gen2第6名:骁龙8Gen1...

继番茄小说后,字节再推免费网文 App“蛋花小说”和“常读小说”

据Tech星球报道,字节跳动公司近期推出了两款全新的免费网文App,分别是“蛋花小说”和“常读小说”。这两款产品的开发公司分别为湖北福瑞兴网络科技有限公司和湖北聚合润网络科技有限公司,均为字节跳动的1...

全世界最好用的AI软件排名是?

Hey小伙伴们,今天咱们来聊聊那些让人爱不释手的AI神器!在这个智能化时代,谁还没几个拿得出手的AI软件呢?别急,我这就给你盘点一波全球超火的AI软件,保证让你大开眼界!...

手机root软件哪个成功率高?手机root软件排行榜2025

作为游戏玩家,欲在手游中畅玩无阻,root权限不可或缺,可优化画质、启用辅助。2025年已至,究竟哪些手机root软件能脱颖而出?哪款软件的root成功率会独占鳌头?一、手机root软...

独立站新手教程引流篇:如何优化谷歌广告投放效果?

随着谷歌广告单价的持续上涨,如何在提升投放效果的同时,降低推广费用成为每一个独立站卖家的必修课。因此新手卖家在完成初步的广告投放流程后,最重要的就是了解一下谷歌广告优化的基础策略。设置转化跟踪即利用G...

云媒易:干货知识分享!海外推广的渠道有哪些,如何正确的选择?

越来越多的海外企业或国内的跨境商家认识到海外的网络营销的作用,开展线上外贸营销,渠道是非常的重要,那么海外的推广渠道有哪些?企业应该如何选择呢?1、社交媒体推广社交媒体推广是现在海外推广方式中最热门的...

取消回复欢迎 发表评论: