Understand this in Js
JavaScript
The scope is static scopestatic scope
, but inJs
In-housethis
But it is an exception.this
The pointing problem is similar to dynamic scope, which does not care about how functions and scope are declared and where they are declared, but only where they are called.this
The pointing of the function cannot be determined when the function is defined, and can only be determined when the function is executed.this
Who is it, of coursethis
The ultimate point to the object that calls it.
Scope
Let's learn about it firstJavaScript
scope to understand whythis
More similar to dynamic scope, generally speaking, the name used in a piece of program code is not always valid or available, and the scope of code that qualifies the availability of this name is the scope of this name.scope
, when a method or member is declared, it has the current execution contextcontext
Environment, with specific valuescontext
In the case, expressions are visible and can be referenced. If a variable or other expression is not in the current scope, it will not be used. Scopes can also be layered according to the code hierarchy so that the child scope can access the parent scope, usually referring to searching along a chain scope chain, and not referring variables and references in the child scope from the parent scope.JavaScript
The scope is static scopestatic scope
, also known as lexical scopelexical scope
, its main feature is that when a local variable that is neither a parameter nor defined within the function scope is encountered in the function scope, the context is checked when defining the function, and corresponding to it is the dynamic scope.dynamic scope
However, when the function scope encounters a local variable that is neither a parameter nor a defined internal function, it is checked in the context of the function call.
var a = 1; var s = function(){ (a); }; (function(){ var a = 2; s(); // 1 })();
Calling s() prints a to 1, which is a static scope, that is, the scope is specified when declaring, and if it is a dynamic scope, 2 will be printed here. Nowadays, most languages adopt static scopes, for exampleC
、C++
、Java
、PHP
、Python
And so on, dynamic scoped languages includeEmacs Lisp
、Common Lisp
、Perl
wait.
Global scope
The variable or method directly declared at the top level runs in the global scope, borrowing the function[[Scopes]]
Properties to view scope,[[Scopes]]
It is an object that saves the function scope chain, and it is the internal properties of the function that cannot be directly accessed, but can be printed for viewing.
function s(){} (s); /* ... [[Scopes]]: Scopes[1] 0: Global ... */ // You can see the statementsThe context in which the function runs is the global scope
Function scope
After declaring a function, the method or member's running environment declared inside the function is the function scope of this function
(function localContext(){ var a = 1; function s(){ return a; } (s); })(); /* ... [[Scopes]]: Scopes[2] 0: Closure (localContext) {a: 1} 1: Global ... */ // You can see the statementsThe context in which the function runs is a functionlocalContextScope of,It can also be called local scope
Block-level scope
If there is a code blocklet
orconst
, the code block will form a closed scope for the variables declared by these commands from the beginning of the block.
{ let a = 1; function s(){return a;} (s); /* ... [[Scopes]]: Scopes[2] 0: Block {a: 1} 1: Global ... */ } // You can see the statementsThe context in which the function runs isBlockBlock-level scope,Also local scope
analyze
We're usingthis
It is necessary to understand whyJavaScript
There must bethis
Before this design, let's give a small example, usually we usethis
The typical problem that we may encounter during the process is similar to the following. Although we run the same function, the execution results may be different.
var obj = { name: 1, say: function() { return ; } }; = 2; = ; (()); // 1 (()); // 2
The reason for this result is that it is usedthis
Keywords, mentioned earlierthis
It must be determined at runtime, here, for()
To be honest,say()
The running environment isobj
Object, for()
To be honest,say()
The running environment iswindow
object, so the results of the two runs differently.
Now let's find out whyJavaScript
There will bethis
Let's first understand this designJavaScript
the stack in the memory structure, heapheap
It is dynamically allocated memory, and will not be automatically released if the size is not determined.stack
The memory space is automatically allocated and is automatically released during code execution.JavaScript
Provide a supply in the stack memoryJs
The environment for code execution, scope and function calls are executed in the stack memory.Js
Basic data typesString
、Number
、Boolean
、Null
、Undefined
、Symbol
, the space occupied is small and the size is fixed. The value is directly stored in the stack memory and is accessed by value.Object
The reference type, whose pointer is placed in the stack memory, points to the actual address of the heap memory, is accessed through a reference.
So at this time, let's take a look at the above example, in memory forobj
The object is stored in heap memory. If the property value in the object is a basic data type, it will be stored in the same memory area as the object, but the property value may also be a reference type, so forsay
This function also exists in heap memory. In fact, here we can understand it as the actual definition of this function is in a memory area (in the form of an anonymous function), andobj
This object is also in another memory area.obj
passsay
This property points to the memory address of the anonymous function.obj --say--> funtion
, then the problem is here. Due to this memory structure, we can make any variable object, etc. point to this function, so inJavaScript
The function needs to allow us to obtain the value of the running environment for use. We must have a mechanism to obtain the current running environment inside the function body.context
,sothis
It appears, and its design purpose is to refer to the current running environment of the function inside the function body.
use
We need to rememberthis
It is bound at runtime, not at definition time, itscontext
Depend on various conditions when calling the function, simply putthis
The binding and the location of the function declaration have nothing to do with it, it only depends on the method of calling the function. To put it simplythis
Always point to the caller, except for the arrow function. Next, we will introduce five typesthis
Use status.
Default binding
The most commonly used function call type is independent function call, which is also the lowest priority.this
Point to global objects, note if strict mode is usedstrict mode
, then the global object will not be able to use the default binding, sothis
Will becomeundefined
。
var a = 1; // Variable declared to global objectfunction f1() { return ; } function f2() { "use strict"; return this; } (f1()); // 1 // Actually, it calls window.f1() and this always points to the caller, i.e. window(f2()); // undefined // Actually it's a call window.f2() At this time, due to strict modeuse strictSo inside the functionthisforundefined
Implicit binding
Only the top or last layer in the object attribute reference chain will affectthis
, toothis
Always point to the caller, specifically, it should point to the nearest caller, except for the arrow function. In addition, we may intentionally or unintentionally create indirect reference land situations, which also applies tothis
Point to the caller, the examples used in the above analysis are indirect references.
function f() { (); } var obj1 = { a: 1, f: f }; var obj2 = { a: 11, obj1: obj1 }; obj2.(); // 1 // The last layer caller isobj1
function f() { (); } var obj1 = { a: 1, f: f }; var obj2 = { a: 11, }; = ; // Indirect quotation(); // 11 // The caller isobj2
Show bindings
If we want to force a function to an environment, that is, an object, then we can use itapply
、call
、bind
Forced bindingthis
Just execute, eachFunction
All objects existapply()
、call()
、bind()
The function of the method is to call functions in a specific scope, which is equivalent to setting the function body.this
The value of the object is to expand the scope on which the function depends for operation. In addition, you need to pay attention to the use ofbind
Bindthis
The priority is greater thanapply
andcall
, that is, usebind
Bindthis
The following function usesapply
andcall
It cannot be changedthis
Pointed.
= "A"; // name mounted to window object = "B"; // name mounted to document objectvar s = { // Customize an object s name: "C" } var rollCall = { name: "Teacher", sayName: function(){ (); } } (); // Teacher // apply (); // A // Default binding to window without passing parameters(window); // A // Bind window object(document); // B // Bind document object(s); // C // Bind custom objects // call (); // A // Default binding to window without passing parameters(window); // A // Bind window object(document); // B // Bind document object(s); // C // Bind custom objects // bind // The last () is to let it execute()(); //A // Default binding to window without passing parameters(window)(); //A // Bind window object(document)(); //B //B //Bind document object(s)(); // C // Bind custom objects
new binding
existJavaScript
middlenew
is a syntax sugar that can simplify the writing of code, and can create object instances in batches.new
The process actually performs the following operations.
Create an empty simpleJavaScript
The object is{}
. Link the object (i.e., set the constructor of the object) to another object. Put the steps1
The newly created object isthis
The context ofcontext
. If the function does not return an object, then return the step1
The object created.
function _new(base,...args){ var obj = {}; obj.__proto__ = ; (obj, args); return obj; } function Funct(a) { = a; } var f1 = new Funct(1); (); // 1 var f2 = _new(Funct, 1); (); // 1
Arrow function
The arrow function is not separatethis
, used in the function body of the arrow functionthis
When the context is obtainedcontext
In the environmentthis
. The arrow function will not generate the scope of thethis
, it will only inherit from the previous layer of its scope chainthis
. Since the arrow function does not have its ownthis
Pointer, useapply
、call
、bind
Only parameters can be passed but not dynamically change arrow functionsthis
Point, and the arrow function cannot be used as a constructor,new
An exception is thrown when instantiated.
= 1; var obj = { name: 11, say: function(){ const f1 = () => { return ; } (f1()); // 11 // The direct caller is window, but since the arrow function does not bind this, this in the context, i.e. obj object const f2 = function(){ return ; } (f2()); // 1 // The direct caller is a normal function of window so return ; } } (()); // 11 // The direct caller isobj Inside functions during executioncontextofthisforobjObject
Example
function s(){ (this); } // Call directly in window // non-use stricts(); // Window // is equivalent to (), the caller is window// window is an instance of Window // window instance of Window //true // Create new object s1var s1 = { t1: function(){ // Test this pointing to the caller (this); // s1 s(); // Window // This call is still equivalent to (), the caller is window }, t2: () => { // Test the arrow function, this does not point to the caller (this); }, t3: { // Objects in the test object tt1: function() { (this); } }, t4: { // Test arrow functions and non-function calls this do not point to the caller tt1: () => { (this); } }, t5: function(){ // When testing the function call, the arrow function's pointer is pointed to the caller of the previous layer object return { tt1: () => { (this); } } } } s1.t1(); // s1 object // The caller here is s1 so the print object is s1s1.t2(); // Window s1.t3.tt1(); // s1.t3 objects1.t4.tt1(); // Window s1.t5().tt1(); // s1Object
This is the end of this article about in-depth understanding of this in Js. For more related and in-depth understanding of this content in Js, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!