this pointing problem in JS

Reproduced at: Blogger link

Trust me, just remember 7 of this article ️⃣ Step by step, you can completely master this point in JS.
Forethought formula: arrow function, new, bind, apply and call, Obi point (obj.) Directly called, not in the function.
According to the order of the pithy formula, as long as the previous scene is satisfied, it can be determined that this points to.
Next, explain them in detail according to the pithy order. The sample code in this article runs in Chrome's Console.
There are carefully prepared exercises at the end of the article to test the learning results. Don't forget to try~

  1. Arrow function
    The arrow function ranks first because its this will not be changed, so as long as the current function is an arrow function, there is no need to look at other rules.
    This of the arrow function is the point of this when it was created. There are two key points here:

When you create the arrow function, you have determined its this point.
This in the arrow function points to this in the outer layer.

Therefore, to know this of the arrow function, you must first know the direction of this in the outer layer, and you need to continue to apply the seven step formula in the outer layer.
2. new
When calling a function with the new keyword, this in the function must be a new object created by JS.
Readers may ask, "if you use the new key to call the arrow function, will this of the arrow function be modified?".
Let's try it on the console.
func = () => {}
new func() // throw error

As can be seen from the console, the arrow function cannot be used as a constructor, so it cannot be executed together with new.
3. bind
Bind refers to function prototype. bind().
When binding multiple times, only the value of the first bind is recognized
Error prone point

Click to view the code
function func() {
  console.log(this)
}

func.bind(1).bind(2)() // 1

this will not be modified in the arrow function

Click to view the code
func = () => {
  // Here, the direction of this depends on the outer layer this. Refer to formula 7 "not in function"
  console.log(this)
}

func.bind(1)() // Window, formula 1 first

bind and new
Error prone point

Click to view the code
function func() {
  console.log(this, this.__proto__ === func.prototype)
}

boundFunc = func.bind(1)
new boundFunc() // Object true, formula 2 takes precedence
4. apply and call The first parameter of apply() and call() is this. The difference is that when called through apply, the arguments are placed in the array, while when called through call, the arguments are comma separated. this will not be modified in the arrow function Error prone point Click to view the code
func = () => {
  // Here, the direction of this depends on the outer layer this. Refer to formula 7 "not in function"
  console.log(this)
}

func.apply(1) // Window, formula 1 first
this will not be modified in the bind function Error prone point Click to view the code
function func() {
  console.log(this)
}

boundFunc = func.bind(1)
boundFunc.apply(2) // 1. Pithy formula 3 is preferred
5. Obi point (obj.) Click to view the code
function func() {
  console.log(this.x)
}

obj = { x: 1 }
obj.func = func
obj.func() // 1
There is no need for code examples here. The arrow function and bind function have higher priority. If you are interested, you can try it yourself. 6. Direct call When the function does not meet the previous scenario and is called directly, this will point to the Global object. In the browser environment, the Global object is Window, and in node JS environment is Global. Let's start with a simple example. Click to view the code
function func() {
  console.log(this)
}

func() // Window
For a complex example, the outer func has a confusing purpose. Click to view the code
function outerFunc() {
  console.log(this) // { x: 1 }

  function func() {
    console.log(this) // Window
  }

  func()
}

outerFunc.bind({ x: 1 })()
  1. Not in function
    Scenes that are not in the function can be divided into the < script / > tag of the browser or node JS module file.
    In the < script / > tag, this points to Window.
    On node JS Module file, this points to the default export object of Module, that is, Module exports.
    Non strict mode
    The strict model is proposed in ES5. Before the ES5 specification, that is, in non strict mode, this cannot be undefined or null. Therefore, in the non strict mode, through the above seven step formula, if it is concluded that this point is undefined or null, then this will point to the Global object. In the browser environment, the Global object is Window, and in node JS environment is Global.
    For example, in the following code, in non strict mode, this points to the global object.
Click to view the code
function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()

The execution result in non strict mode is:

In strict mode, execute the same code for comparison. Remember to copy and paste all the code into the console at once to run in strict mode (because the first line of "use strict" will take effect for subsequent code).

Click to view the code
"use strict"

function a() {
  console.log("function a:", this)
  ;(() => {
    console.log("arrow function: ", this)
  })()
}

a()

a.bind(null)()

a.bind(undefined)()

a.bind().bind(2)()

a.apply()

The execution result in strict mode is:

The seven step formula is complete in strict mode and non strict mode, but null or undefined will be converted to global objects in non strict mode. So I didn't include this in the formula.
Review questions
Recite the formula first and then do the questions, "arrow function, new, bind, apply and call, Obi point (obj.) Call directly, not in function ".

  1. After the following code is executed, func What is the count value?
Click to view the code
function func(num) {
  this.count++
}

func.count = 0
func(1)

answer
func. The count value is 0.
According to the formula, when func() is called, it belongs to category 6 "direct call". In non strict mode, this points to the global object. This has nothing to do with func, so func Count remains unchanged. so easy.
2. Who does this point to in the following arrow function?

Click to view the code
obj = {
  func() {
    const arrowFunc = () => {
      console.log(this._name)
    }

    return arrowFunc
  },

  _name: "obj",
}

obj.func()()

func = obj.func
func()()

obj.func.bind({ _name: "newObj" })()()

obj.func.bind()()()

obj.func.bind({ _name: "bindObj" }).apply({ _name: "applyObj" })()
answer // obj // undefined // newObj // undefined // bindObj Copy code Isn't it very simple? Have you failed?

Keywords: Javascript

Added by raccer on Tue, 11 Jan 2022 16:52:21 +0200