About “this”

P1: How to use this?

  • This is actually a binding that happens when the function is called, and what it points to depends entirely on where the function is called.

    This is easy to say, but often difficult to understand. Take a look at the code below
    var a =1;
    var obj = {
        a : 0.say: function(){ console.log(this.a) }
    }
    var fun = obj.say;
    obj.say(); / / 0
    fun();     / / 1
    Copy the code
  • Why is this happening? Fun and obj.say refer to the same function and are both called in the window object. Why are the results different?

The essence is this:

     obj.say()  // equivalent to obj.say.call(obj); If you don't write.call(obj), the browser will write it for youFun () is equivalent to fun.call(window) 
Copy the code
  1. theobjAs athisIntroduced to thesayThe natural output of the function isobjWithin thea
  2. inwindowObject executionfun(), is equivalent to takingwindowAs athisIt’s passed into the function, and the output iswindowIn thea!
  • More generically, this actually accompanies our code all the time
    • You callfun()In fact, it was executedfun.call(undefined)
    • You callobj.fun()Actually executedobj.fun.call(obj)

If you pass null or undefined, the window is passed by default (in strict mode the default is undefined) so far we have covered the basic usage of this

P2: How do we determine if this points to?

  • If you want to judge a function that’s runningthisBind, you need to find the direct call location of this function. Once found, you can apply the following four rules in order of prioritythisThe binding object of.
  1. Called by new, it is bound to the newly created object.
  2. Show binding: called by call or apply (or bind)? Binds to the specified object.
  3. Implicit binding: invoked by context objects.
    function say(){ console.log(this.name) }
    let person = { name:'Jam'.age: 18.say: say}
    person.say() // 'Jam'
    Copy the code
  4. Default binding: bound to undefined in strict mode, otherwise bound to global objects.

P3: This in the arrow function

  • The “this” object inside the arrow function is the object at which it is defined, not the object at which it is used. Arrow functions do not have their own “this” (arrow functions cannot use call,apply), and arrow functions default to the parent “this”.

I don’t know how other people understand it, but it’s a definition I don’t understand. What is the object of the definition? How to use parent this? Let me give you an example.

let obj = {
	prin: function(){
        // The parent scope holds the parent's this
	    setTimeout(() = >{
	        console.log(this.num);
        },1000)}}let obj1 = { num:1 };
let obj2 = { num:2 };
Copy the code
  1. Let’s try it out by executing the PRin method

    obj.prin(); // undefined
    Copy the code

    Analysis: Obj.prin () is equivalent to obj.prin.call(obj). We pass obj as this to prin and the arrow function looks up the this saved in the parent scope and finds obj. Obj does not have num property inside obj, so print undefined

  2. Try changing the reference to this in the parent

    obj.prin.call(obj1); / / 1
    obj.prin.call(obj2); / / 2
    Copy the code

    In the same way that this in the parent is assigned obj1 and finds the num property and prints its value, the arrow function is assigned obj2 and finds the num property and prints its value

  3. Why don’t we just give obj a num attribute?

    obj.num = 0;
    obj.prin(); / / 0
    Copy the code

    Analysis: when obj has num, the arrow function finds it!

  4. Let’s do one last example to deepen our understanding! What happens when I write the prin function as an arrow function?

    var num = 10.// "ancestor scope" window
    var obj = {
        num : 5;
        prin: () = >{
            // The parent scope holds the parent's this
            setTimeout(() = >{
                console.log(this.num);
            },1000)
        }
    }
    obj.prin()
    Copy the code

    What can you guess? The answer is 10!

    Analysis: The arrow function in setTimeout looks for this in the parent scope and finds that the parent scope is also an arrow function, so it looks out again and finds the “parent scope” Window, which happens to have num property. So the arrow function in setTimeout happily prints window.num!

P4: Some other summaries

  1. Using let, const variables may not conform to this conclusion. The reason is: let, const variables declared in global scope are not added to the window property like var, so even if let number = 1 is declared in global scope, arrow functions, etc., will not find number in global scope!

This paper draws on zhuanlan.zhihu.com/p/23804247 @ party shall hang the teacher’s thought