Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”.

This knowledge point is often involved in the interview questions, this must understand!!

This is a concept that many people will confuse, but in fact it is not difficult at all, but many articles on the Internet have complicated simple things. In this article, you will surely understand the concept of “this” thoroughly.

Let’s start with a few function call scenarios

function foo() {
    console.log(this.a)
}
var a = 1;
foo();

const obj = {
    a: 2.foo: foo
}
obj.foo()

const c = new foo()
Copy the code

Let’s look at each of these scenarios one by one

  • For direct callsfooSay, no matterfooWhere does the function go,thisIt must bewindow
  • forobj.foo()So, we just have to remember, whoever called the function isthisSo in this scenariofooThe function this isobjobject
  • fornewIn the manner of,thisIt’s bound to forevercAbove, it will not be changed in any waythis

Now, having said that, there’s no problem with this in a lot of code, so let’s look at this in the arrow function, okay

function a() { 
    return () = > { 
        return () = > { 
            console.log(this)}}}console.log(a()()())
Copy the code

First, the arrow function doesn’t actually have this. The “this” in the arrow function depends only on the “this” of the first normal function that wraps the arrow function. In this case, because the first normal function that wraps the arrow function is a, this is the window. In addition, using functions such as bind for arrow functions does not work.

The last case is the context-changing API called bind. For these functions, this depends on the first argument, or if the first argument is empty, the window.

So speaking of bind, have you ever thought about what the context would be if you bind a function multiple times?

let a = {} 
let fn = function () { 
    console.log(this) 
} 
fn.bind().bind(a)() / / = >?
Copy the code

If you think the output is a, you are wrong. We can actually convert the above code to a different form

/ / fn. The bind (). The bind is equal to (a)
let fn2 = function fn1() { 
    return function() { 
        return fn.apply() 
    }.apply(a) } 
fn2()
Copy the code

As you can see from the above code, no matter how many times we give bind, this in fn is always determined by the first bind, so the result is always window.

let a = { name: 'yck' } 
function foo() { 
    console.log(this.name) 
} 
foo.bind(a)() // => 'yck'
Copy the code

That’s the rule for this, but it’s possible to have multiple rules at the same time, and the different rules will decide where this ends up depending on which rule has the highest priority.

First, the new method takes precedence, followed by the bind method, followed by the obj.foo() method, and finally the foo method. Meanwhile, the arrow function’s this, once bound, cannot be changed by any method.

If you’re still feeling a little convoluted, take a look at the flow diagram below, which is for a single rule.