当前位置:恩施知识网 > 健康之路 > 正文

JavaScript中this关键字是什么呢

ES6以来,大量加入的新语法极大地方便了我们编程的同时,也增加了很多我们理解的心智负担。要想认识这些函数的执行上下文切换,我们必须要对他们行为上的区别有所了解。
对普通变量而言,这些函数并没有本质区别,都是遵循了'继承定义时的环境'的规则,它们的一个行为差异在于this关键字。
那么,this 关键字是什么呢?
this 关键字行为
this 是JavaScript中的一个关键字,它的使用方法类似一个变量(但是this跟变量有很多不同)。
this是执行上

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

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

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

this 关键字行为

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

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

Function showThis(){console.info(this)}var o = {showThis: showThis}showThis(); //globalo.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(); // globalo.showThis(); // global我们看到,改为箭头函数后,无论用什么来调用它,都不影响它的this值。

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

class C {showThis() {console.log(this);}}var o = new C();var showThis = o.showThis;showThis(); // undefinedo.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); // 2console.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(); // undefinedo.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

JavaScript中this关键字是什么呢

如何理解 JavaScript 中的 this 关键字

this是Javascript语言的一个关键字它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用,随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。
情况一:纯粹的函数调用
这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。
情况二:作为对象方法的调用
函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
情况三 作为构造函数调用
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。
情况四 apply调用
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。

JavaScript中this关键字是什么呢

如何理解 JavaScript 中的 this 关键字

this是Javascript语言的一个关键字。
它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用。比如,
function test(){
this.x = 1;
}
随着函数使用场合的不同,this的值会发生变化。但是有一个总的原则,那就是this指的是,调用函数的那个对象。
下面分四种情况,详细讨论this的用法。
情况一:纯粹的函数调用
这是函数的最通常用法,属于全局性调用,因此this就代表全局对象Global。
请看下面这段代码,它的运行结果是1。
function test(){
this.x = 1;
alert(this.x);
}
test(); // 1
为了证明this就是全局对象,我对代码做一些改变:
var x = 1;
function test(){
alert(this.x);
}
test(); // 1
运行结果还是1。再变一下:
var x = 1;
function test(){
this.x = 0;
}
test();
alert(x); //0
情况二:作为对象方法的调用
函数还可以作为某个对象的方法调用,这时this就指这个上级对象。
function test(){
alert(this.x);
}
var o = {};
o.x = 1;
o.m = test;
o.m(); // 1
情况三 作为构造函数调用
所谓构造函数,就是通过这个函数生成一个新对象(object)。这时,this就指这个新对象。
function test(){
this.x = 1;
}
var o = new test();
alert(o.x); // 1
运行结果为1。为了表明这时this不是全局对象,我对代码做一些改变:
var x = 2;
function test(){
this.x = 1;
}
var o = new test();
alert(x); //2
运行结果为2,表明全局变量x的值根本没变。
情况四 apply调用
apply()是函数对象的一个方法,它的作用是改变函数的调用对象,它的第一个参数就表示改变后的调用这个函数的对象。因此,this指的就是这第一个参数。
var x = 0;
function test(){
alert(this.x);
}
var o={};
o.x = 1;
o.m = test;
o.m.apply(); //0
apply()的参数为空时,默认调用全局对象。因此,这时的运行结果为0,证明this指的是全局对象。
如果把最后一行代码修改为
o.m.apply(o); //1
运行结果就变成了1,证明了这时this代表的是对象o。
摘自阮一峰老师的博客。
免责申明:以上内容属作者个人观点,版权归原作者所有,不代表恩施知识网立场!登载此文只为提供信息参考,并不用于任何商业目的。如有侵权或内容不符,请联系我们处理,谢谢合作!
当前文章地址:https://www.esly.wang/jiankang/42521.html 感谢你把文章分享给有需要的朋友!
上一篇:什么是不会聊天不会聊天怎么办,不会聊天有什么软件能帮忙聊天吗 下一篇:男人不想和你亲密接触的原因「两性交往男人不接近你的14个主要原因以及该怎么做」

文章评论