This in JavaScript is a major headache for many developers, and the this keyword is a very important syntax point. It’s no exaggeration to say that most development tasks can’t be accomplished without understanding what it means.

1. Event call environment

  • Who triggers this points to who
<! DOCTYPE html><html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="Width = device - width, initial - scale = 1.0">
 <title>Document</title>  <style>  .box{  width: 100px;  height: 100px;  background: # 999;  margin: 10px;  }  </style> </head> <body>  <div class="box box1">box1</div>  <div class="box box2">box2</div> </body> <script>  const box1 = document.querySelector('.box1');  const box2 = document.querySelector('.box2');   box1.onclick = clickBox;  box2.onclick = clickBox;   function clickBox() { console.log(this);  }; </script> </html> Copy the code

In the code above, bind the clickBox methods to box1 and box2, respectively. If box1 is clicked, this in the clickBox will refer to the currently clicked box1 element.

2. Inside the function this points to

(1) When test is called directly in non-strict mode, this refers to window
function test() {    console.log(this); // window
};
test(a);Copy the code
(2) When calling test directly in strict mode, this refers to undefined
'use strict';
function test() {    console.log(this); // undefined
};
test(a);Copy the code
(3) Object this points to
  • This ultimately refers to the object on which it was called
  • Functions are contained in multiple layers of objects. If a function is called by the outermost object, this refers to the object at the next level above it.

B is a method on obj. When executed through obj or window.obj. B, it is the method b that is called from obj above B, and this refers to obj.

var obj = {
    a:'11'.    b:function() {console.log(this); //obj    }
}; obj.b(); window.obj.b(); Copy the code

Similarly, when fn is called, fn is called by b, so this refers to B.

var obj = {
    a:'11'.    b:{
        fn:function() {console.log(this); // b }  } }; obj.b.fn(); Copy the code

If obj.b.fn is copied to ABC, then fn is not executed. Instead, fn is assigned to ABC, and ABC is a function. When ABC is executed, it is window.

var obj = {
    a:'11'.    b:{
        fn:function() {console.log(this); //window }  } }; let abc = obj.b.fn; console.log(typeof abc); //function abc(); Copy the code

constructor

The constructor needs to use the new keyword, which can be used in the following steps:

  • 1. Call the function
  • 2. Automatically create an empty object
  • 3. Bind the created object to this
  • 4. This is implicitly returned if the constructor (Fn) does not return a value, or if (Fn) does return a value (e.g. : return {d:’d’}).

Check that this points to (no return value)

function Fn() {    this.num = 1;
}
Fn.num = 2;
Fn.prototype.num = 3;
Fn.prototype.method = function() { console.log(this); }; Copy the code

Method refers to Fn because there is no this.method method inside Fn. So we look for method on prototype, where this points to the Fn constructor;

Num =1; if this.num=1, call prototype.num, and then newfn. num will be 3.

Num: Fn. Num: Fn. Num: Fn. Num

var newFn = new Fn();
newFn.method();
console.log(newFn.num);
console.log(Fn.num); / / 2Copy the code

Prototype (Fn. Prototype); method (method); method (Fn. Prototype); Num = Fn. Prototype. num = 3; , num in method is 3;

var prototype = Fn.prototype;
prototype.method();
Copy the code

If we assign prototype.method to the method variable again, then the method level above is window, and this is window (non-strict mode, undefined).

var method = prototype.method;
method();
Copy the code

If the constructor has a return value, and the return value is an object, array, function, Date, RegExp, etc., then the relevant methods on Fn refer to the returned object, such as {dd:’11’}

function Fn() {    this.num = 1;
    return {
        dd:'11'
    }
} Fn.num = 2; Fn.prototype.num = 3; Fn.prototype.method = function() { console.log(this); }; Copy the code

{dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’} {dd:’11’}

var newFn = new Fn();
newFn.method();
Copy the code

Arrow function

  • The arrow function itself does not have this and arguments; referencing this in the arrow function actually calls this of the scope defined at the previous level. (Objects are not scoped)

As we saw above, when a method on an object executes, this points to the parent that called it. This is fine when called by the obj.c method, but if it is an arrow function, the arrow function this is scoped to the upper level when the arrow function is defined, and the object is not scoped, because the d method this refers to the upper level window object in non-strict mode.

var obj = {
    c:function() {        console.log(this);
    },
    d:()=>{
 console.log(this);  } }; obj.c(); // objobj.d(); // windowCopy the code

5. Modify the this pointer

  • This can be done through call,apply, and bind