✏️ 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
- The default refers to the value of [x.xx] in a function that is not called by a dot
this
Point to global [window] - Implicit: for a function, if called by a dot, the inside of the function
this
Points to the object that called the function - Explicit pointing: Through
Call, apply, bind
I’m changing theta in the functionthis
Points to the specified object - New keyword: of the constructor
this
Points 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
apply
Both change the point of this to a function and execute the function. The difference is that the parameter list is differentbind
Changes 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
-
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
-
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
- in
Person
The first line in the function implicitly generates an objectvar this = {}
- To make the
this
The stereotype of points to the stereotype of the functionthis.__proto__ = Person.prototype
- perform
Person
function - Let’s put this in the last line of the function
this
Return 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