✏️ When you say “this” in Js, you think of “this” in a function. This in Js is no exception. Let’s take a look at the rule that this points to in Js

✅ In JS, there are four rules that affect the direction of this

  1. The default refers to the value of [x.xx] in a function that is not called by a dotthisPoint to global [window]
  2. Implicit: for a function, if called by a dot, the inside of the functionthisPoints to the object that called the function
  3. Explicit pointing: ThroughCall, apply, bindI’m changing theta in the functionthisPoints to the specified object
  4. New keyword: of the constructorthisPoints to the instantiated object

If the above four conditions exist at the same time, then their priority is 4 > 3 > 2 > 1

One, the default point

If [x.xx] is not called, this in the function refers to the global [window].

1) 🛴 Let’s take a small example of 30km/h

var age = 18;
function showAge () {
  var age = 100;
  console.log('my age is: ' + this.age);
}
showAge();
Copy the code

Run as my age is: 18

In this small example, the showAge function is not called when executing, such as ×××.showage (), so this in the showAge function refers to the global window, i.e. this. Age is the global age of 18.

Some of you might wonder, why not print 100. The first thing to be clear is that in this small example, we are printing this.age instead of age, so instead of looking for the age variable, look for console.log(‘my age is: ‘+ age) to print 100.

2) 🏍 another small example of 60km/h

var age = 18; var obj = { age : 100, showAge : function () { setTimeout(function () { console.log('my age is: ' + this.age); }, 300); Return 'please wait 300 milliseconds '; } } obj.showAge();Copy the code

Run as my age is: 18

Huh??????? Why still 18?? In fact, it is also consistent with the rules to clarify where functions are executed. First, the showAge function is defined in an object with a timer, setTimeout, that waits 300 milliseconds to print. That should be fine. ShowAge () calls the showAge method in obj, so this in showAge points to obj. However, the statement we’re going to operate on is in the setTimeout function inside the timer. So we can simulate setTimeout roughly

function setTimeout (callback, delay) { ... if (...) { callback(); }... }Copy the code

This function should refer to the global object window. This function should refer to the global object window. This function should refer to the global object window. So what’s printed is the global age, which is equal to 18.

It also leads to a general conclusion: the generic callback function this points to the global object window. 【 Except arrow function 】

Two, implicit pointing

For a function that is called by a dot, the “this” in that function refers to the object that called it

1) 🛴 Let’s look at an example of 30kN /h

var age = 18;
var obj = {
    age : 100,
    showAge : function () {
      console.log('my age is: ' + this.age);
    }
}
obj.showAge();
Copy the code

The result is my age is: 100

ShowAge () is called by the object obj, so this in the showAge function refers to the object obj, so you can also read the showAge execution statement as console.log(‘my age is: ‘+ obj.age), so print the age on object obj, which is 100.

2) 🏍 Here’s another example of 60km/h

var obj1 = {
    age : 18,
    showAge : function () {
      console.log('my age is: ' + this.age);
    }
}
var obj2 = {
    age : 100,
    showAge : function () {}
}
obj2.showAge = obj1.showAge;
obj2.showAge();
Copy the code

The result is my age is: 100

First, run obj2.showAge = obj1.showAge to refer to the showAge function of obj1 to the showAge function of obj2, So the showAge execution of obj2 becomes the showAge execution of obj1 and then we execute obj2.showage (), shoeAge this points to obj2, so we print the age of obj2, which is 100.

Three, display pointing

Call, apply, and bind change this to refer to the specified object

Call Apply bind

  • call applyBoth change the point of this to a function and execute the function. The difference is that the parameter list is different
  • bindChanges the point of this to a function and returns a new function that accepts only the first binding of this

1) 🛴 Let’s take an example of 30km/h

var obj = { age : 100, showAge : function () { console.log('my age is: ' + this.age); } } var newObj = { age : 18 } obj.showAge.call(newObj); //var func = obj.showage.bind (newObj); // bind (); // bind (); // The result is the same as call applyCopy the code

The result is: my age is: 18

First, the execution statement looks left to right, calls the showAge method in the obj object, and then uses the call method to change this in the showAge method to a newObj object. Log (‘my age is: ‘+ newObj. Age), so print newObj’s age, which is 18.

2) 🚗 analyze the principle of call change this, the speed is 100km/h

First, we know in implicit reference that this in a function, if called by a dot, refers to the object that called the function, so we can use this to simulate the call method

Function.prototype.myCall = function (context) { var ctx = null; If (context) {CTX = json.parse (json.ify (context)); }else { ctx = window; } var arg = arguments, len = arg.length, args = []; ctx.fn = this; for (var i = 1; i < len; Push ('arg[' + I + ']'); push('arg[' + I + ']); } // args = ['arg[1]', 'arg[2]',...  var result = eval( 'ctx.fn(' + args.join(',') + ')' ); Fn (arg[1], arg[2],...) ') delete ctx.fn; return result; }Copy the code

My age is: 18

First of all, the myCall function is ok, and then let’s analyze what’s going on inside the function

  1. Change this to the target context by turning the function calling myCall into a method in the target context by ctx.fn = this. This means that the function calling myCall refers to the target context

  2. Integrate the parameters of the function calling myCall, parse the string into a script using the eval method, and execute it

Instantiate an object with new

The this constructor points to the instantiated object

1) 🛴 Let’s take an example of 30km/h

function Person (name, age) {
    this.name = name;
    this.age = age;
    this.introduceYourself = function () {
      console.log('my name is ' + this.name, 'and I\'m ' + this.age + ' years old.');
    }
}
var person = new Person('xuyede', 18);
person.introduceYourself();
Copy the code

My name is xuyede and I’m 18 years old.

To better understand, you can break down the new Person() process into four steps

  1. inPersonThe first line in the function implicitly generates an objectvar this = {}
  2. To make thethisThe stereotype of points to the stereotype of the functionthis.__proto__ = Person.prototype
  3. performPersonfunction
  4. Let’s put this in the last line of the functionthisReturn to go out

So, it can be understood that the variable person gets a reference to this in the constructor, so person can use the value set on this in the constructor.

2) 🏎 see what the new has done, 180km/h

function myNew() { var func = [].shift.call(arguments); Var instance = object.create (func.prototype); var instance = object.create (func.prototype); // Declare a context where the stereotype is the constructor stereotype func.apply(instance, arguments); // Execute the constructor and change this to instance return instance; // Return the context}Copy the code

Fifth, the