Without further ado, let’s look at a few function call scenarios

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

let a = 1;
foo();

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

const c = new foo();
Copy the code

Next, analyze the above scenarios one by one

  • For calling foo directly, no matter where foo is placed, this must refer to window, right

  • For obj.foo(), just remember that whoever called the function is this, so this in the foo function is the obj object in this scenario

  • For new, this is permanently bound to C and cannot be changed in any way

Look again at this in the arrow function

function a() {
  return () => {
    return ()=> {
      console.log(this);
    };
  };
};

console.log(a()()());
Copy the code

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

In the end, this is the case with the bind context-changing API. For these functions, this depends on the first argument, and if the first argument is null, then the window.

If you bind a function multiple times

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

You can actually convert the appellate code into another form

let fn2 = function fn1() {
  return function() {
    return fn.apply()
  }.apply(a)
};

fn2();
Copy the code

As you can see from the appeal 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: 'xyz' };
function foo() {
  console.log(this.name);
};

foo.bind(a)(); // => 'xyz'
Copy the code

When multiple rules occur at the same time, different rules will determine where this points according to the highest priority.

First, the new method takes precedence, followed by functions like bind, then obj.foo(), and finally foo, and the arrow function’s this, once bound, can’t be changed in any way.

Finally, there is a flow chart for this to help clarify the thinking (for a single rule only).

—END—