Before we get to this, it’s important to understand the life cycle of a function

When you call a function, you go through the process of creating the function and then executing it. And this points to the re-creation phase that’s already done. For the creation and execution phases, see the following figure: I have written a knowledge article – click on transfer

For example, a person. The getName (); When this line of code is executed, it undergoes the creation of the function.

Execute the context life cycle describe
create The context creates the variable object, validates the scope chain, and determines the this point
perform After the creation phase, the code executes, which completes variable assignments, function references, and other code

This and scope operations are identified at function creation time, meaning that this is identified at creation stage, and is not affected by the internal code of the function.

But it doesn’t mean that the function can be determined at the definition stage. Prepare to say that a function goes through a define-call-then create-execute phase.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — artificial line — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

5 examples of perfect parsing this parsing

Chestnut one:

function a() {
	console.log('1')
}
a();
Copy the code

First, whoever calls this points to who.

So who calls a()? In non-strict mode, the default is window.a(); In strict mode, this call will return an error. So you can see that if you use this inside of A, you’re essentially pointing to the window object

Chestnut 2:

	var a = 1;
    function fn() {
        var a = 2;
        console.log(a);   / / 2
        console.log(this.a); / / 1
    }
    fn();  // In non-strict mode equivalent to window.fn();
Copy the code

Again: whoever calls this points to whoever

Chestnuts three:

var o = {
    a:10.b: {a:12.fn:function(){
            console.log(this.a); //undefined
            console.log(this); //window}}}var j = o.b.fn;
j();
Copy the code

Because j() is actually window.j(); So when j () is executed, this points to the window. Don’t be fooled by appearances, remember the maxim: whoever calls this points to whoever

Chestnut 4: This under the new keyword

function Person(){
    this.name = "tony";
}
var tony = new Person();
console.log(tony.name); //tony 
Copy the code

Why does Tony have a name property? See why this. Name = ‘Tony’ applies to the Tony object?

The new keyword is special because the new keyword actually does the following:

  • First create an empty, New instance object (the object returned by New (func))
  • Points the prototype of the instance object to the prototype of the constructor
  • Change the constructor’s this to refer to an instance object, which is Tony, and this to refer to Tony
  • Returns the instance object (special case: if the constructor itself returns an object or function, then the constructor returns the instance object)

As for how to actually modify this to point to this question later!

Chestnut five:

The specificity of the arrow function to this

I quote teacher Ruan Yifeng’s explanation of arrow function in ES6:

The this object inside the function is the object at which it is defined, not used.

This sentence to be honest, after reading always vaguely understand the feeling. But what is certain is the original: this refers to whoever the function is called by. That doesn’t apply here. And one thing to figure out: How do I find the object of the function definition?

// ES6
const obj = {
  getArrow() {
    return () = > {
      console.log(this); }; }}Copy the code

What happens when it’s executed?

let arrowFn = obj.getArrow(); // The arrowFn will bind the obj object.
let arrowFn2 = obj.getArrow.call(window); // arrowFn will bind the window object
Copy the code

I got it wrong at the beginning:

const obj = {
  getArrow() {
    return () = > {
      console.log(this); }; }}Copy the code

I thought I would be able to confirm the execution of this from this code alone, but the results clearly proved me wrong. Combine to: == “the object on which the function getArrow is defined, not used” ==

The problem with this statement is that:

  • When is the function defined?
  • What is the context in which the function is defined?
// This is the window
console.log(this); // this => window 
const obj = {
  getArrow() {
    return () = > {
      console.log(this); }; }}Copy the code
  • Confusion point 1: Isn’t the definition of the arrow function under this=window?

Answer: No, the arrow function is not actually defined at this point. The definition actually happens when the getArrow() method is called, when obj.getarrow () is executed, and when return ()=>{console.log(this)} is called, it looks for this and binds. So if this is the case when: return ()=>{console.log(this)} is executed, the arrow function points to this.

  • Confusion point 2: Why is the definition of arrow functions not necessarily obj objects?

Answer: The answer to confusion point 1 is sufficient. The key to understand in this example is when the arrow function: return ()=>{console.log(this)} is defined? And the answer is that when you execute this line of code, instead of writing it in obj, the last thing you bind is obj. There are a lot of explanations on the Internet that might not look quite right.

  • Confusion 3: Does a function definition have to happen at execution time?

Answer: This… Here are some examples to answer this question.

Chestnut 6:

	let fnObj = {
        getArrow : () = > {
            console.log(this)
        }
    }

    fnObj.getArrow(); // Print: window
Copy the code

So, when is the getArrow method defined? Before implementation:

	let fnObj = {
        getArrow : () = > {
            console.log(this)}}Copy the code

GetArrow is defined when the main code executes this code. If this is window, the getArrow arrow function binds window. (The arrow function does not have this, so it will look for this as its own when defining it.)

Chestnut 7:

	var id = 'window';
    let foo =  {
        id : 'foo'.arrow: function() {
            setTimeout(() = > {
                console.log(' arrow id:'.this.id);
            }, 100);
        },
        fn: function() {
            setTimeout(function() {
                console.log(' fn id:'.this.id);
            }, 100);
        },
    }
    foo.arrow();  // Think about printing?
    foo.fn();  // Think about printing?
Copy the code
  • Foo.fn () answer: Print window

Reason: The setTimeout function is executed by the window call, so printing window makes sense.

  • Arrow () answer: Print foo

Why: The key to understanding this example is to understand: when are anonymous function parameters defined in setTimeout? I’m sure I can understand this problem by writing it a different way.

 	fn: function() {
            setTimeout(() = > {
                console.log(' arrow id:'.this.id);
            }, 100);
        },
    // -- "is equivalent to the following writing
     fn: function() {
     		// The arrowFn arrow function points to something that you don't understand
     		let arrowFn = () = > {
                console.log(' arrow id:'.this.id);
            }
            setTimeout(arrowFn, 100);
        },
Copy the code

Don’t be fooled by appearances. Focus the problem on this: the context in which the arrow function is defined.

———————————Ending——————————————-

  • Thank you very much for pointing out any mistakes
  • Blogging can be exhausting, but it can be very useful for organizing your own knowledge
  • In the process of writing also found the usual attention to the corners and corners