JavaScript 中的 this

JavaScript 中的 this,第1张

JavaScript 中的this关键字通常是该语言初学者的困惑之源。这种混淆部分源于这样一个事实,即JavaScript 中的this与其他语言(如 Java 或 Python 中的 self)的处理方式不同。为了理解 JavaScript 中更高级的概念或读写 JavaScript 代码,
理解这一点是绝对必要的,这就是为什么我们将在本文中试图阐明这在 JavaScript 中的真正含义。
我们将在本文的大部分时间里参考 JavaScript 中的函数来学习这方面的知识,这就是为什么我们首先要了解一个关于 JavaScript 函数的事实,它可以帮助我们更好地做到这一点。
 

this 和函数

JavaScript 中的函数本质上是对象。像对象一样,它们可以分配给变量,传递给其他函数并从函数返回。就像对象一样,它们也有自己的属性。这些属性之一是this。this
存储的值是 JavaScript 程序的当前执行上下文。因此,当在函数内部使用时,this的值将根据该函数的定义方式、调用方式和默认执行上下文而改变。注意:这始终包含对单个对象的引用,该对象定义了当前代码行的执行上下文。 

在我们深入研究 this 在函数中的行为之前,让我们看看它在函数之外的行为:
全局上下文: 
在函数外部编写的一行代码被称为属于全局上下文,并且在这个全局上下文中 this 的值是与全局对象相同。
例如,如果您打开浏览器控制台并在其中输入以下行,然后按回车/回车键: 
console.log(this)
您会看到 Window 对象正在登录到控制台。这是因为全局对象在浏览器运行时(例如 Chrome 的运行时)是 Window 对象。 
然而,在函数内部,全局上下文可能不再存在,函数可能有自己定义的上下文,因此 this 的值不同。为了理解这一点,让我们把注意力转向函数:
函数,在 JavaScript 中可以通过多种方式调用:

1.函数调用 

2.方法调用

3. 构造函数调用
 

this与函数调用:

函数调用是指使用函数名称或表达式调用函数的过程,该表达式计算为函数对象,后跟一组打开和关闭的第一个括号(包含括号表示我们正在要求 JavaScript 引擎立即执行该函数)。
例如: 
 

JavaScript

                    

doSomething函数里面的this,如果是通过上面的函数调用来调用的话,它的值就是全局对象,也就是浏览器环境中的window对象:
 

JavaScript

                                             

输出:  

test value

然而,这并非总是如此。如果 doSomething() 函数在严格模式下运行,它将记录undefined而不是全局窗口对象。这是因为,在严格模式下(由行 : 'use strict';表示), this 的默认值,对于任何函数对象都设置为未定义而不是全局对象。 
例如 :  

JavaScript

                                                                

输出:  

undefined
undefined 

 

this与方法调用:

函数,当定义为对象的字段或属性时,称为方法。 

JavaScript

                                                             

输出:  

John is 31 years old 

在上面的代码示例中,logInfo()是person 对象的一个​​方法,我们使用对象调用模式来调用它。 
也就是说,我们使用属性访问器来访问作为对象一部分的方法。
这样的调用需要使用一个表达式来计算我们的方法所属的对象,以及一个属性访问器(例如:person.logInfo()),后跟一组左括号和右括号。
了解函数调用和方法调用的不同之处至关重要。 
这反过来将帮助我们理解this上下文在任何给定函数中可能是什么,因为在每个调用中,this是不同的。
在使用属性访问器调用的此类方法中,this将具有调用对象的值,即this将指向与属性访问器一起使用以进行调用的对象。
例如 :  

JavaScript

                    

输出:  

[object Object] 1
[object Object] 2 

在上面的例子中, calc() 是 add 对象的一个​​方法,因此使用第 9 行和第 10 行的方法调用规则来调用。 
我们知道,当使用方法调用模式时,this的值被设置为调用目的。
在这个 calc() 方法中,this 的值被设置为调用对象,在我们的例子中是 add。因此我们可以成功访问 add 的 num 属性。 
然而,让我们看看一个主要的混淆点:在嵌套在对象方法中的函数中 
会发生什么?

JavaScript

                                                 

输出:  

[object Object] [object Window] NaN
[object Object] [object Window] NaN 

让我们试着理解刚刚发生的事情。 
当我们在第 14 行和第 15 行调用 calc() 时,我们正在使用方法调用,它将this设置为添加到 calc() 中。这可以使用第 4 行中的 log 语句来验证。
但是,使用简单的函数调用(第 11 行)从 calc() 方法中调用 innerfunc()。这意味着,在 innerfunc() 内部,this 被设置为没有 num 属性的全局对象,因此获得了 NaN 输出。
我们如何解决这个问题?我们如何从嵌套函数内部的外部方法中保留 this 的值?
一种解决方案是将外部函数的this值分配给要在嵌套函数中使用的变量,如下所示: 

JavaScript

                                                                     

输出:  

[object Object] [object Object] 1
[object Object] [object Object] 2 

此问题的其他解决方案包括使用 bind()、call() 或 apply(),我们将很快研究这些方法。
 

this 与构造函数调用:

当 new 关键字后跟一个函数名和一组左括号和右括号(带或不带参数)时,将执行构造函数调用。
例如: let person1= new People('John', 21); 
这里,person1 是新创建的对象,People 是用于创建该对象的构造函数。
构造函数调用是在 JavaScript 中创建对象的几种方法之一。 
当我们将 new 关键字与函数名结合使用时,究竟会发生什么? 
通过这种方法创建对象基本上涉及五个步骤。让我们用下面的例子来研究它们: 

JavaScript

                                                                                             

输出:  

John is 21 years old 
首先,创建一个空对象,它是与 new 一起使用的函数名称的实例(即:people(name, age))。换句话说,它将对象的构造函数属性设置为调用中使用的函数(people(name, age))。
 然后,它将构造函数(people)的原型链接到新创建的对象,从而保证这个对象可以继承构造函数的所有属性和方法 
 然后,在这个新创建的对象上调用构造函数。如果我们回想方法调用,我们会看到类似。因此,在构造函数内部,this获取调用中使用的新创建对象的值。 
 最后,将创建的对象及其所有属性和方法集返回给 person1

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1295749.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-10
下一篇 2022-06-10

发表评论

登录后才能评论

评论列表(0条)

保存