I. Thinking:

1. Why can’t methods be defined using arrow functions?

A: Because the arrow function does not have its own scope, it is bound to the context of the parent scope,

If the arrow function is used, this points to the window when retrieving data from data, causing access failure

This is not bound to arrow functions, but if arrow functions use this, the methods object is not scoped (all objects are not scoped).

2. What does this point to without using the arrow function?

A: Vue source code is explicitly bound to a proxy that points to a Vue instance through bind.

2. This refers to:

First of all, we need to know that every function has its own this, but this is not bound to an object when the function is declared. This is bound to an object only when the function is called.

That is, the binding of this has nothing to do with where the function is defined, and everything to do with how the function is called.

Common this points to:

  • In a global scope or normal function, this refers to the global object Window
  • The immediate function this must point to window
  • The timer this points to the window
  • Event this refers to the event source object
  • Method refers to whoever calls it
  • In the constructor, this points to the object instance

3. This binding rule:

1. Default binding rules

1. Bind the global object Window by default

console.log(this === window);   //true
Copy the code

2. Call the function independently in the global scope. This refers to the window

    function test() {
      console.log(this===window);  //true
    }
    test();
Copy the code

Implicit binding rules

Understanding: Whoever calls points to whoever

1. Call a method within an object

let obj = { name: 'obj', foo: function () { console.log(this); //this points to obj}} obj.foo()Copy the code

2. Modify:

let obj = { name: 'obj', foo: function () { console.log(this); //obj function test() { console.log(this); //window why? Because test independently calls} test()}} obj.foo()Copy the code

3. Implicit loss:

let obj = { name: 'obj', foo: function () { console.log(this); //window why not obj? }} let bar = obj.foo bar()Copy the code

4. Function as argument:

function foo() { console.log(this); } function bar(fn) {fn()} let obj = {name: 'obj', foo: foo} bar(obj.foo)Copy the code

4.1 When a function is an argument, the argument function is called a child function, the outer function is called the parent function, and the child function is also called the callback function. There are many functions like this.

For example, forEach, setimeout, arguments in these functions are also called built-in arguments

Remember: the parent function has the ability to determine what the child function this refers to. For example, in forEach, the first argument is a function and the second argument is the object bound to this, not the default window

3. Explicit binding

Call, apply, bind Bind returns a new function that points to the bound object, but the old one does not

4. New binding

This refers to the object after the function is instantiated

5. Priority of binding rules:

New Binding > Explicit Binding > Implicit Binding > Default binding

4. Arrow function this points to the problem:

1. The arrow function does not have its own this; its this points to this in the upper scope

Before 1.1, we wanted the inner function’s this to point to the outer function’s this.

Var a = 0 function foo() {let that = this // point to obj console.log(this); Function test() {console.log(that) // Point to obj} test()} let obj = {a: 1, foo: foo} obj.foo()Copy the code

1.2 Or use bind/call/apply to explicitly bind this to the external function:

var a = 0 function foo() { console.log(this); // point to obj function test() {console.log(this); } test.call(obj) } let obj = { a: 1, foo: foo } obj.foo()Copy the code

2. The arrow function this points to a function that does not follow any of the above four rules:

2.1 Independent calls are invalid for arrow functions:

var a = 0 function foo() { let test = () => { console.log(this) } return test } let obj = { a: 1, foo: Foo} obj.foo()() // obj.foo() returns testCopy the code

Implicit binding does not work with arrow functions:

let a = 0 let obj1 = { a: 1, foo: () => { console.log(this); }} obj1.foo() // points to windowCopy the code

2.3 Explicit binding does not work for arrow functions:

var a = 0 function foo() { let test = () => { console.log(this) } return test } let obj1 = { a: 1, foo: foo } let obj2 = { a: 2, foo: Foo} obj1.foo().call(obj2) //obj1.foo() returns test obj1.foo.call(obj2) binds the pointer to test to obj2, but this still points to obj1Copy the code