Mind mapping

  • With the ‘.’ operator before a function is executed, this in the function body refers to the preceding object, not to the window, and strictly to undefined. This sentence is particularly important, please remember

  • The function has no direct caller this pointing to a global object (window in the browser, global in Node). Such as anonymous functions

  • The constructor’s this points to the instance itself.

  • The arrow function itself does not have this. The arrow function this points to the nearest non-arrow function this, which points to window if not found, and undefined in strict mode.

The pointer to the ordinary function this

  • Warm up the topic 1
var name = 'Lin Yiyi'
function fn(){
    var name = 'Forest two two'
    return this.name
}
fn()    / / linyi
Copy the code

Call fn() without the ‘.’ operator, so this refers to the window. The output is the global name = ‘lin-one-one’.

  • Warm-up questions 2
var name = 'Forest two two'
var obj = {
    name: 'Lin Yiyi'.fn: function () {
        return this.name
    }
}
console.log(obj.fn())   // 'linyiyi'
var fo = obj.fn
console.log(fo())       // 'lin2' fo() ==> window.fo()
Copy the code

The function fn() in obj.fn() is preceded by the ‘.’ operator, so this refers to obj. The fo() function is not preceded by the ‘.’ operator, so this refers to the window. Fo () ==> window.fo(); fo() ==> window.fo()

  • Warm up 3
var name = 'Forest two two'
var obj = {
    name: 'Lin Yiyi'.fn: function () {
        var name = 'small three'
        return function(){
             return this.name
        }
    }
}
console.log(obj.fn()())   / / Lin.
var fo = obj.fn()
console.log(fo())    / / Lin.
Copy the code

Obj.fn ()() returns A function (called function A), and A() does not have A ‘.’ operator, so this refers to window, and the output is Lin22. The fo() function above is the same.

The function has no direct caller

Functions have no direct callers to global objects (window in browsers, global in Nodes), such as anonymous functions. Point to undefined in strict mode

  • Warm up the topic 1
var name = 'Lin Yiyi'; ! (function(){
   console.log(this.name)   / / linyi}) ()Copy the code

The self-executing function has no direct caller output name = ‘lin-one-one’.

  • Warm-up questions 2
var name = 'Lin Yiyi'
var obj = {
    name : '二二'.callback: function(){
        console.log(this.name)
    }
}

setTimeout(obj.callback,1000)
/* Output * linyi */
Copy the code

The setTimeout, obj.callback(which is just a reference address) functions do not have a direct caller; this refers to the window. So the output name is Lin Yiyi in the global context.

Constructor this

Read this: the constructor’s this refers to the instance itself

  • Warm up the topic 1
function Fn(){
    var n = 0
    this.name = 'Lin Yiyi'
    this.age = 18
    this.getName = function(){
        return this.name
    }
}

Fn.prototype.getAge = function(){
    return this.age
}

Fn.x = 'Forest two two'

var f = new Fn()
console.log(f.name)     / / linyi
console.log(f.getName())     / / linyi
console.log(f.getAge())        / / 18
console.log(f.n)    // undefined
console.log(f.x)    // undefined
Copy the code

Fn above is a constructor when new, and this refers to instance f. So the 1,2 output above is Lin 1, 1. F getAge() is 18. F getAge() is 18. F getAge() is 18. A: this is the prototype chain lookup mechanism, properties of x is not on the prototype prototype is not instance attributes, you can read this article interview | you have to know the JS prototype and prototype chain; Q: why is the output of f.n undefined? Because the variable n is private to the constructor and has nothing to do with the instance new creates.

Arrow function

The arrow function itself does not have this. The arrow function’s this inherits the context. The this in the arrow function refers to the current nearest non-arrow function’s this.

The arrow function’s this is defined, not executed

  • Warm up the topic 1

var name = 'Lin Yiyi'
var obj = {
    name: '二二'.a: () = > {
        console.log(this.name)
    }
}
obj.a()

/* output * 'linyiyi' */
Copy the code

This of the arrow function. If you can’t find this of the non-arrow function, you point directly to the window.

  • Warm-up questions 2
var name = 'Lin Yiyi'
var obj = {
    name: '二二'.fn: function() {
        return () = > {
            console.log(this.name)
        }
    }
}
obj.fn()()

/* Outputs * 'two two' */
Copy the code

It is clear that the arrow function’s this comes from fn, and the object obj calls fn, so fn’s this points to obj, and the output is 2, 2.

Change the direction of this

Tip: All functions are created based on the Function base class, and also have FunctionThe method above the prototype

  • Call, an object that accepts this, and a list. Apply is just like Call, except that apply accepts an array of arguments. Bind also changes the this pointer to the function, except that it returns a new function whose arguments are derived from the remaining arguments
  • Warm up the topic
var name = 'Lin Yiyi'
var age = 18
function fn(){
   return this.name
}

function p(){
    return {
        age: this.age,
        arg: arguments}}let obj = {
    name: '二二'.age: 18
}

let o = {
    name: 'since'
}

fn()    // 'linyiyi'
fn.call(obj)    // '2 2'
fn.call(o)  //  '三三'
p.call(obj, 12.23.45.67) // {age: 18, arg: Arguments(4)}

fn.apply(obj)    // "two two"
p.apply(obj, [1.2.3.4.5])    // {age: 18, arg: Arguments(5)}

fn.bind(obj)()  // "two two"
p.bind(obj, 12.23.34) ()// {age: 18, arg: Arguments(3)}
Copy the code

So that’s call, apply, bind for this.