SoFunction
Updated on 2025-04-06

Deep understanding of this in javascript

Understand this in Js

JavaScriptThe scope is static scopestatic scope, but inJsIn-housethisBut it is an exception.thisThe 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.thisThe pointing of the function cannot be determined when the function is defined, and can only be determined when the function is executed.thisWho is it, of coursethisThe ultimate point to the object that calls it.

Scope

Let's learn about it firstJavaScriptscope to understand whythisMore 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 contextcontextEnvironment, with specific valuescontextIn 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.
JavaScriptThe 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 scopeHowever, 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 exampleCC++JavaPHPPythonAnd so on, dynamic scoped languages ​​includeEmacs LispCommon LispPerlwait.

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 blockletorconst, 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 usingthisIt is necessary to understand whyJavaScriptThere must bethisBefore this design, let's give a small example, usually we usethisThe 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 usedthisKeywords, mentioned earlierthisIt must be determined at runtime, here, for()To be honest,say()The running environment isobjObject, for()To be honest,say()The running environment iswindowobject, so the results of the two runs differently.
Now let's find out whyJavaScriptThere will bethisLet's first understand this designJavaScriptthe stack in the memory structure, heapheapIt is dynamically allocated memory, and will not be automatically released if the size is not determined.stackThe memory space is automatically allocated and is automatically released during code execution.JavaScriptProvide a supply in the stack memoryJsThe environment for code execution, scope and function calls are executed in the stack memory.JsBasic data typesStringNumberBooleanNullUndefinedSymbol, the space occupied is small and the size is fixed. The value is directly stored in the stack memory and is accessed by value.ObjectThe 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 forobjThe 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 forsayThis 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), andobjThis object is also in another memory area.objpasssayThis 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 inJavaScriptThe 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,sothisIt appears, and its design purpose is to refer to the current running environment of the function inside the function body.

use

We need to rememberthisIt is bound at runtime, not at definition time, itscontextDepend on various conditions when calling the function, simply putthisThe 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 simplythisAlways point to the caller, except for the arrow function. Next, we will introduce five typesthisUse status.

Default binding

The most commonly used function call type is independent function call, which is also the lowest priority.thisPoint to global objects, note if strict mode is usedstrict mode, then the global object will not be able to use the default binding, sothisWill 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, toothisAlways 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 tothisPoint 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 itapplycallbindForced bindingthisJust execute, eachFunctionAll 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.thisThe 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 ofbindBindthisThe priority is greater thanapplyandcall, that is, usebindBindthisThe following function usesapplyandcallIt cannot be changedthisPointed.

 = "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

existJavaScriptmiddlenewis a syntax sugar that can simplify the writing of code, and can create object instances in batches.newThe process actually performs the following operations.

Create an empty simpleJavaScriptThe object is{}. Link the object (i.e., set the constructor of the object) to another object. Put the steps1The newly created object isthisThe context ofcontext. If the function does not return an object, then return the step1The 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 functionthisWhen the context is obtainedcontextIn 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 ownthisPointer, useapplycallbindOnly parameters can be passed but not dynamically change arrow functionsthisPoint, and the arrow function cannot be used as a constructor,newAn 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!