We are all familiar with the keyword this in JavaScript. Depending on the different runtime environment this is in, some expressions and differences are easy to confuse people. Before carefully understanding this, MY understanding of it is very stiff and one-sided.

The origin of this

Let’s take a look at this chestnut:

var name = 'MyWindow'

function SayHi() {
  console.log('Hi, My name is ' + name + '. ')}var MyJavaScript = {
  name: 'MyJavaScript'.sayHi: SayHi,
}

SayHi() // Hi, My name is MyWindow.
MyJavaScript.sayHi() // Hi, My name is MyWindow.
Copy the code

As you can see, when we’re trying to print Hi, My name is MyJavaScript. “, still output window. Because the value of the name variable printed in the SayHi function must be looked up along the scope chain of the current execution environment.

The SayHi function is called to create its own execution environment, the three elements of the execution environment

  1. Variable object: Defines all variables and methods that are accessible within the current execution environment.
  2. Chain of scope: Essentially a chain of variable objects formed in the order of nesting in the execution environment.

A scope is a set of rules for finding variables by name. It determines which variables can be accessed in a given execution environment. A scope chain defines parent scopes that have access to them in addition to the current scope. By default, when we access a variable, we look through the scope chain, first finding the nearest scope (the current scope) and then looking at the outer scope.

Scope chain diagram

In scope nesting order, SayHi is nested in the global execution environment. When we look inside SayHi for the name variable, we automatically find the name variable in the outer global scope, so we output window no matter how we call it.

How do we print the name property of the MyJavaScript object when we call myjavascre.sayhi ()?

Thump, thump, thump, thump, this was born!! (With BGM)

  1. this: is used to point toThe actual runtime environment for the function.

Let’s rewrite the SayHi method:

var name = 'MyWindow'

function SayHi() {
  // Change here
  console.log('Hi, My name is ' + this.name + '. ')}var MyJavaScript = {
  name: 'MyJavaScript'.sayHi: SayHi,
}

SayHi() // Hi, My name is MyWindow.
MyJavaScript.sayHi() // Hi, My name is MyJavaScript.
Copy the code

As shown in the figure above, when we change the name to this.name, the sayHi function, when called as a property of the MyJavaScript object, prints the exact value of the name property of the MyJavaScript object that called the current function.

From this we can see that the purpose of this object is to give us the object that actually called the function when it is called under different execution circumstances. It doesn’t matter where the function is defined or the scope of the function, it only matters how the function is called.

These are the previous lives of this object. The following will sort out some essential knowledge points related to this object, for you to refer to.

A few things you need to know

What is this

This is a JavaScript keyword that, in non-strict mode, always points to an object, which is dynamically bound based on the execution environment in which the function is run.

Why we need this

Because functions can be executed in different runtime environments, either by themselves or as a method call, this mechanism was born in order to get the actual execution environment in which the current function actually runs, that is, the actual object that the function calls when it executes.

What does this do

(ditto) refers to the actual calling object of the function.

This point

A simple call

This defaults to a global object in the global environment, undefined in strict mode, and window in the browser.

E.g. func() => this defaults to a global object => window (under the browser).

Method calls as objects

The this point is determined by the method of invocation and is determined at function execution time.

E.g. obj.func() => this refers to the specific calling object => obj.

Here we can understand that obj.f1() is found by object obj, so it runs in the obj environment, this refers to obj.

As a constructor

When a function is used as a constructor (using the new keyword), its this is bound to the new object being constructed and is returned as the default value of the constructor.

This point depends on the object returned by the function (default uninitialized value => undefined), and in class context (class keyword) depends on the object returned by the class constructor (default returns all properties and methods defined in the class, excluding static methods).

The function context defaults to this

No initialization value

Manually Adding properties

Function context is returned manually

The class context defaults to this

The class context constructor is returned manually

Do you want to go back? Almost over ah, hold on 👋

Arrow function

We know that the reference to this for ordinary functions is determined during function execution, depending on how the function is called.

In the ES6 arrow function, this is defined when the function is defined and always refers to the environment object in which the function is declared. This cannot be changed in any other way.

A static method

Because the this object represents the object that called the function, and the static method belongs to the class and not to the calling object, the calling object may not exist after the static method has successfully loaded. Therefore, the value of this object cannot be found in a static method.

Anonymous functions

The reference to this in an anonymous function is also determined by how the function is called.

Foo is called as objA’s method, and this refers to objA.

Foo is referred to the anonymous function that obja. foo points to, and when foo is simply called, this refers to the global object.

SetTimeout and setInterval

When using setTimeout and setInterval, this in the callback defaults to the window object, because setTimeout and setInterval are the methods provided by the Window object.

As you can see, the output in setTimeout is the count attribute on the window object.

Really really the 99th step, stick to it 👋

Several ways and differences to change what this refers to

call

apply

The difference between call and apply

Call parameters are put directly in, second, third… The NTH arguments are all separated by commas.

The second argument to apply receives an array that is passed to the bound function.

bind

The use of bind is the same as that of call, but bind returns the bound function and requires an additional manual call.

That’s the end of this article, thank you for reading, if there are any mistakes welcome to discuss