What is this? An in-depth analysis of this in JavaScript
Aug 04, 2022 pm 05:02 PMWhat is this? The following article will introduce you to this in JavaScript, and talk about the differences between this in different calling methods of functions. I hope it will be helpful to you!
this
in JavaScript
is particularly different, such as in
Java language this
cannot be changed during the execution phase of the code, while JavaScript's this
is bound during the calling phase. Because of this nature, it gives this
a lot of room for development. But it is somewhat different in strict mode and non-strict mode, and the different calling methods of the function also lead to some differences in this.
What is this?
First define this: This is a variable determined when the execution context is created that cannot be changed during execution.
The so-called execution context is the JavaScript engine that uses some variables and functions before executing a piece of code. , thisA process that is declared in advance and then stored in a variable object. This 'code snippet' includes: Global code (code inside the script tag), Function internal code, eval internal code. The scope chain we are familiar with will also be saved here, stored in an array-like form in the [[Scopes]] attribute of the corresponding function.
This is only determined during the function call phase, that is, when the execution context is created, it is assigned and stored in the variable object. This feature also leads to the variability of this: that is, when the function is called in different ways, the value of this may be different.
We said above that this behaves differently in strict mode and non-strict mode:
var?a?=?1; function?fun()?{ ???'use?strict'; ????var?a?=?2; ??????return?this.a; } fun();//報錯?Cannot?read?property?'a'?of?undefined
In strict mode, this points to undefined;
var?a?=?1; function?fun()?{ ????var?a?=?2; ??????return?this.a; } fun();//1
In non-strict mode this points to window;
The same piece of code above behaves differently in different modes because Because this is different in strict mode and non-strict mode.
Conclusion: When a function is called independently, its this points to undefined in strict mode. In non-strict mode, when this points to undefined, it automatically points to the global object (that is, in the browser window)
One more thing, in the global environment, this points to itself, look at another example:
this.a?=?1; var?b?=?1; c?=?1; console.log(this?===?window)//true //這三種都能得到想要的結(jié)果,全局上下文的變量對象中存在這三個變量
One more thing, when this is not used in the function What will happen? Look at an example:
var?a?=?1000; var?obj?=?{ ????a:?1, ??????b:?this.a?+?1 } function?fun()?{ ????var?obj?=?{ ??????????a:?1, ????????c:?this.a?+?2?//嚴格模式下這塊報錯?Cannot?read?property?'a'?of?undefined ????} ????return?obj.c; } console.log(fun());//1002 console.log(obj.b);//1001
In this case, this still points to the window. Then we can draw a separate conclusion:
When obj is declared globally, this in the internal properties of obj points to the global object. When obj is declared in a function, in strict mode this will Points to undefined, non-strict mode automatically changes to point to the global object.
Okay, I just tried my hand at it, and I know the difference between this in strict mode and non-strict mode. However, the most common use in our daily life is to use this in functions. I also mentioned this above. There are differences in the different calling methods of functions. So what are the calling methods of functions? Four types:
- Directly call
- as the method of the object in the global environment or ordinary function
- Use apply and call
- as the constructor Function
is expanded on the following four situations:
Direct call
The above example is actually a direct call, but I Decided to write another example:
var?a?=?1; var?obj??=??{ ????a:?2, ??????b:?function?()?{ ????????function?fun()?{ ??????????return?this.a ????????} ???????console.log(fun()); ????} }? obj.b();//1
Although the fun function is defined in the obj.b method, it is still an ordinary function. When called directly, it points to undefined in non-strict mode, and automatically points to the global object, as expected. , strict mode will report the error undefined.a is not established, a is not defined.
I’ll say the important thing again: When a function is called independently, its this points to undefined in strict mode. In non-strict mode, when this points to undefined, it automatically points to the global object ( In the browser, it is window).
As a method of an object
var?a?=?1; var?obj?=?{ ??a:?2, ??b:?function()?{ ????return?this.a; ??} } console.log(obj.b())//2
The anonymous function referenced by b is called as a method of obj. At this time, this points to the object that calls it. This is obj. So what if method b is not called as an object method? What does it mean? This is it:
var?a?=?1; var?obj?=?{ ??a:?2, ??b:?function()?{ ????return?this.a; ??} } var?t?=?obj.b; console.log(t());//1
As above, the execution result of the t function turns out to be global variable 1. Why? This involves the memory space of Javascript. That is to say, the b attribute of the obj object stores a reference to the anonymous function, which can be understood as a pointer. When assigning a value to t, it does not open up a separate memory space to store the new function. Instead, t stores a pointer that points to this function. It is equivalent to executing such a piece of pseudo code:
var?a?=?1; function?fun()?{//此函數(shù)存儲在堆中 ????return?this.a; } var?obj?=?{ ??a:?2, ??b:?fun?//b指向fun函數(shù) } var?t?=?fun;//變量t指向fun函數(shù) console.log(t());//1
At this time, t is a pointer to the fun function. Calling t is equivalent to calling fun directly. Applying the above rules, printing out 1 is naturally easy to understand.
使用apply,call
關(guān)于apply和call是干什么的怎么用本文不涉及,請移駕:apply,call
這是個萬能公式,實際上上面直接調(diào)用的代碼,我們可以看成這樣的:
function?fun()?{ ??????return?this.a; } fun();//1 //嚴格模式 fun.call(undefined) //非嚴格模式 fun.call(window)
這時候我們就可以解釋下,為啥說在非嚴格模式下,當函數(shù)this指向undefined的時候,會自動指向全局對象,如上,在非嚴格模式下,當調(diào)用fun.call(undefined)的時候打印出來的依舊是1,就是最好的證據(jù)。
為啥說是萬能公式呢?再看函數(shù)作為對象的方法調(diào)用:
var?a?=?1; var?obj?=?{ ??a:?2, ??b:?function()?{ ????return?this.a; ??} } obj.b() obj.b.call(obj)
如上,是不是很強大,可以理解為其它兩種都是這個方法的語法糖罷了,那么apply和call是不是真的萬能的呢?并不是,ES6的箭頭函數(shù)就是特例,因為箭頭函數(shù)的this不是在調(diào)用時候確定的,這也就是為啥說箭頭函數(shù)好用的原因之一,因為它的this固定不會變來變?nèi)サ牧恕jP(guān)于箭頭函數(shù)的this我們稍后再說。
作為構(gòu)造函數(shù)
何為構(gòu)造函數(shù)?所謂構(gòu)造函數(shù)就是用來new對象的函數(shù),像Function
、Object
、Array
、Date
等都是全局定義的構(gòu)造函數(shù)。其實每一個函數(shù)都可以new對象,那些批量生產(chǎn)我們需要的對象的函數(shù)就叫它構(gòu)造函數(shù)罷了。注意,構(gòu)造函數(shù)首字母記得大寫。
function?Fun()?{ ??this.name?=?'Damonre'; ??this.age?=?21; ??this.sex?=?'man'; ??this.run?=?function?()?{ ????return?this.name?+?'正在跑步'; ??} } Fun.prototype?=?{ ??contructor:?Fun, ??say:?function?()?{ ????return?this.name?+?'正在說話'; ??} } var?f?=?new?Fun(); f.run();//Damonare正在跑步 f.say();//Damonare正在說話
如上,如果函數(shù)作為構(gòu)造函數(shù)用,那么其中的this就代表它即將new出來的對象。為啥呢?new做了啥呢?
偽代碼如下:
function?Fun()?{ ??//new做的事情 ??var?obj?=?{}; ??obj.__proto__?=?Fun.prototype;//Base為構(gòu)造函數(shù) ??obj.name?=?'Damonare'; ??...//一系列賦值以及更多的事 ??return?obj }
也就是說new做了下面這些事:
- 創(chuàng)建一個臨時對象
- 給臨時對象綁定原型
- 給臨時對象對應(yīng)屬性賦值
- 將臨時對象return
也就是說new其實就是個語法糖,this之所以指向臨時對象還是沒逃脫上面說的幾種情況。
當然如果直接調(diào)用Fun(),如下:
function?Fun()?{ ??this.name?=?'Damonre'; ??this.age?=?21; ??this.sex?=?'man'; ??this.run?=?function?()?{ ????return?this.name?+?'正在跑步'; ??} } Fun(); console.log(window)
其實就是直接調(diào)用一個函數(shù),this在非嚴格模式下指向window,你可以在window對象找到所有的變量。
另外還有一點,prototype對象的方法的this指向?qū)嵗龑ο?,因為實例對象?code>__proto__已經(jīng)指向了原型函數(shù)的prototype。這就涉及原型鏈的知識了,即方法會沿著對象的原型鏈進行查找。
箭頭函數(shù)
剛剛提到了箭頭函數(shù)是一個不可以用call和apply改變this的典型。
我們看下面這個例子:
var?a?=?1; var?obj?=?{ ??a:?2 }; var?fun?=?()?=>?console.log(this.a); fun();//1 fun.call(obj)//1
以上,兩次調(diào)用都是1。
那么箭頭函數(shù)的this是怎么確定的呢?箭頭函數(shù)會捕獲其所在上下文的 ?this
值,作為自己的 this
值,也就是說箭頭函數(shù)的this在詞法層面就完成了綁定。apply,call方法只是傳入?yún)?shù),卻改不了this。
var?a?=?1; var?obj?=?{ ??a:?2 }; function?fun()?{ ????var?a?=?3; ????let?f?=?()?=>?console.log(this.a); ??????f(); }; fun();//1 fun.call(obj);//2
如上,fun直接調(diào)用,fun的上下文中的this值為window,注意,這個地方有點繞。fun的上下文就是此箭頭函數(shù)所在的上下文,因此此時f的this為fun的this也就是window。當fun.call(obj)再次調(diào)用的時候,新的上下文創(chuàng)建,fun此時的this為obj,也就是箭頭函數(shù)的this值。
再來一個例子:
function?Fun()?{ ????this.name?=?'Damonare'; } Fun.prototype.say?=?()?=>?{ ????console.log(this); } var?f?=?new?Fun(); f.say();//window
有的同學(xué)看到這個例子會很懵逼,感覺上this應(yīng)該指向f這個實例對象啊。不是的,此時的箭頭函數(shù)所在的上下文是__proto__
所在的上下文也就是Object函數(shù)的上下文,而Object的this值就是全局對象。
那么再來一個例子:
function?Fun()?{ ????this.name?=?'Damonare'; ??????this.say?=?()?=>?{ ????????console.log(this); ????} } var?f?=?new?Fun(); f.say();//Fun的實例對象
如上,this.say所在的上下文,此時箭頭函數(shù)所在的上下文就變成了Fun的上下文環(huán)境,而因為上面說過當函數(shù)作為構(gòu)造函數(shù)調(diào)用的時候(也就是new的作用)上下文環(huán)境的this指向?qū)嵗龑ο蟆?/p>
【相關(guān)推薦:javascript學(xué)習(xí)教程】
The above is the detailed content of What is this? An in-depth analysis of this in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undress AI Tool
Undress images for free

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

WebSocket and JavaScript: Key technologies for realizing real-time monitoring systems Introduction: With the rapid development of Internet technology, real-time monitoring systems have been widely used in various fields. One of the key technologies to achieve real-time monitoring is the combination of WebSocket and JavaScript. This article will introduce the application of WebSocket and JavaScript in real-time monitoring systems, give code examples, and explain their implementation principles in detail. 1. WebSocket technology

How to use WebSocket and JavaScript to implement an online speech recognition system Introduction: With the continuous development of technology, speech recognition technology has become an important part of the field of artificial intelligence. The online speech recognition system based on WebSocket and JavaScript has the characteristics of low latency, real-time and cross-platform, and has become a widely used solution. This article will introduce how to use WebSocket and JavaScript to implement an online speech recognition system.

Introduction to how to use JavaScript and WebSocket to implement a real-time online ordering system: With the popularity of the Internet and the advancement of technology, more and more restaurants have begun to provide online ordering services. In order to implement a real-time online ordering system, we can use JavaScript and WebSocket technology. WebSocket is a full-duplex communication protocol based on the TCP protocol, which can realize real-time two-way communication between the client and the server. In the real-time online ordering system, when the user selects dishes and places an order

JavaScript and WebSocket: Building an efficient real-time weather forecast system Introduction: Today, the accuracy of weather forecasts is of great significance to daily life and decision-making. As technology develops, we can provide more accurate and reliable weather forecasts by obtaining weather data in real time. In this article, we will learn how to use JavaScript and WebSocket technology to build an efficient real-time weather forecast system. This article will demonstrate the implementation process through specific code examples. We

How to use WebSocket and JavaScript to implement an online reservation system. In today's digital era, more and more businesses and services need to provide online reservation functions. It is crucial to implement an efficient and real-time online reservation system. This article will introduce how to use WebSocket and JavaScript to implement an online reservation system, and provide specific code examples. 1. What is WebSocket? WebSocket is a full-duplex method on a single TCP connection.

JavaScript tutorial: How to get HTTP status code, specific code examples are required. Preface: In web development, data interaction with the server is often involved. When communicating with the server, we often need to obtain the returned HTTP status code to determine whether the operation is successful, and perform corresponding processing based on different status codes. This article will teach you how to use JavaScript to obtain HTTP status codes and provide some practical code examples. Using XMLHttpRequest

Usage: In JavaScript, the insertBefore() method is used to insert a new node in the DOM tree. This method requires two parameters: the new node to be inserted and the reference node (that is, the node where the new node will be inserted).

Introduction to the method of obtaining HTTP status code in JavaScript: In front-end development, we often need to deal with the interaction with the back-end interface, and HTTP status code is a very important part of it. Understanding and obtaining HTTP status codes helps us better handle the data returned by the interface. This article will introduce how to use JavaScript to obtain HTTP status codes and provide specific code examples. 1. What is HTTP status code? HTTP status code means that when the browser initiates a request to the server, the service
