preface

Refer to the following articles

40 more questions for this interview

First, there are several ways to bind this

  • Default binding (in non-strict mode this refers to global object, in strict mode this is bound to undefined)

  • Implicit binding (when a function references a context object, such as the way obj.foo() is called, where this in foo refers to obj)

  • Show bindings (specify this bindings directly via call() or apply(), such as foo.call(obj))

  • The new binding

  • Arrow function binding (the reference of this is determined by outer scope)

The function this points to

Execute the function immediately; this executes the window

1. Ordinary functions

This always refers to the object that last called it.

var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj'.foo1: function () {
      console.log(this.name);
      return function () {
        console.log(this.name)
      }
    },
  
  }
}
var person1 = new Person('person1')
var person2 = {name: 'person2'}

person1.obj.foo1() // The last object to call is obj, output obj
person1.obj.foo1()()  // obj, window, the first () function executes the output obj, return is a function, the second () function executes immediately, this executes the window,
person1.obj.foo1.call(person2)()
person1.obj.foo1().call(person2)

Copy the code

The output

Arrow function

This is defined by the outer scope and refers to this at function definition time, not execution time.

var name = 'window'
function Person (name) {
  this.name = name
  this.obj = {
    name: 'obj'.foo2: function () {
    console.log(this.name);
      return () = > {
        console.log(this.name)
      }
    }
  }
}
var person1 = new Person('person1')
var person2 = new Person('person2')

person1.obj.foo2()() // The first () executes the output obj, and the last call is obj. The second () calls the execute arrow function, whose scope is foo2, and this points to obj
person1.obj.foo2.call(person2)()
person1.obj.foo2().call(person2)

Copy the code

The output

To reassure

1.use strictThis points to in strict mode

Instead of all pointing to undefined, global this points to window, and this points to undefined inside a function

"use strict";
var a = 10;
function foo () {
  console.log('this1'.this) // this1 undefined
  console.log(window.a) / / 10
  console.log(this.a) // This is undefined
}
console.log(window.foo) // Print the function
console.log('this2'.this) // This points to window
foo();

Copy the code

The output

2,Var and let and constDifferences in declared variables

Variables declared by let and const are not bound to the window object, so this refers to the window, which does not have this variable, and is undefined

let a = 1
const b = 2

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

Copy the code

The execution result

Implicit loss of implicit binding

There are two situations where loss can occur

  • Use another variable to alias the function
function foo () {
  console.log(this.a)
};
var obj = { a: 1, foo };
var a = 2;
var foo2 = obj.foo;

obj.foo(); / / 1
foo2();  / / 2

Copy the code

Obj.foo () this refers to the object that last called this function, so it naturally points to obj output 1

Foo2 () implicitly loses the pointer, and the last call is window, so it points to window and outputs 2

  • 2. The function is implicitly assigned when passed as an argument, and the callback loses the this binding
function foo () {
  console.log(this.a)
}
function doFoo (fn) {
  console.log(this)
  fn()
}
var obj = { a: 1, foo }
obj2 = { a: 3, doFoo}
var a = 2
doFoo(obj.foo)
obj2.doFoo(obj.foo)

Copy the code

The output

  • 1.doFoo(ob.foo()When executed,doFoo() This points to the window,
  • 2,obj.foo() namelydoFooParameters insidefn()Implicitly missing, this refers to window

  • 3,obj2.doFoo(obj.foo)When executed,doFoo()This points to obj2,
  • 4. Inside parametersfn()Implicit missing, this refers to the window, so implicit missing has nothing to do with the outer this pointerfn()Is called by window. This refers to window.

4. Timer package functions also have implicit loss problems

var obj1 = {
  a: 1
}
var obj2 = {
  a: 2.foo1: function () {
    console.log(this.a)
  },
  foo2: function () {
    setTimeout(function () {
      console.log(this) // window
      console.log(this.a) / / 3
    }, 0)}}var a = 3

obj2.foo1() / / 2
obj2.foo2()

Copy the code