это указывает на проблему в JS

JavaScript

Поверьте мне, если вы запомните 7️⃣ шагов из этой статьи, вы сможете полностью понять указатель this в JS.

Сначала прочтите формулу: стрелочные функции, новые, привязка, применение и вызов, объект, прямой вызов, а не в функции.

По порядку формул, пока выполняется один из предыдущих сценариев, можно определить, что это указывает на.

Далее они будут подробно объяснены в порядке формул.Примеры кодов в этой статье выполняются в консоли консоли Chrome.

В конце статьи есть хорошо подготовленные практические вопросы для проверки результатов обучения, не забудьте попробовать~

1. Стрелочные функции

Стрелочная функция идет первой, потому что это не будет изменено, поэтому, пока текущая функция является стрелочной, нет необходимости смотреть на другие правила.

this стрелочной функции — это указатель на внешнее this при его создании. Здесь есть два важных момента:

  1. При создании стрелочных функций, уже установлено, на что это указывает.
  2. это внутри функции стрелки указывает навнешнее это.

Таким образом, чтобы узнать this функции стрелки, вы должны сначала узнать точку внешнего this, и вам нужно продолжать применять формулу из семи шагов во внешнем слое.

2. new

При вызове функции с новым ключевым словом this в функции должен быть новым объектом, созданным JS.

Читатели могут задаться вопросом: «Если стрелочная функция вызывается с новой клавишей, будет ли изменена this стрелочной функции?».

Попробуем на консоли.

func = () => {}
new func() // throw error

new-arrow-function-error.png

Как видно из консоли, стрелочные функции нельзя использовать в качестве конструкторов, поэтому их нельзя выполнять с помощью new .

3. bind

связывать средстваFunction.prototype.bind().

При многократном связывании распознается только значение первого связывания.

подвержен ошибкам

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

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

это не будет изменено в функциях стрелок

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.bind(1)() // Window,口诀 1 优先

переплет и новый

подвержен ошибкам

function func() {
  console.log(this, this.__proto__ === func.prototype)
}

boundFunc = func.bind(1)
new boundFunc() // Object true,口诀 2 优先

4. подать заявку и позвонить

apply()а такжеcall()Первым параметром является this, разница в том, что фактические параметры помещаются в массив при вызове с помощью применения, а фактические параметры разделяются запятыми при вызове с помощью вызова.

это не будет изменено в функциях стрелок

подвержен ошибкам

func = () => {
  // 这里 this 指向取决于外层 this,参考口诀 7 「不在函数里」
  console.log(this)
}

func.apply(1) // Window,口诀 1 优先

Это не будет изменено в функции привязки

подвержен ошибкам

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

boundFunc = func.bind(1)
boundFunc.apply(2) // 1,口诀 3 优先

5. Оби Терм (объект)

function func() {
  console.log(this.x)
}

obj = { x: 1 }
obj.func = func
obj.func() // 1

Здесь нет необходимости приводить пример приоритета стрелочных функций и функций привязки, если вам интересно, вы можете попробовать их сами.

6. Прямой звонок

Когда функция не удовлетворяет предыдущему сценарию и вызывается напрямую, это будет указывать на глобальный объект. Глобальным объектом является Window в среде браузера и Global в среде Node.js.

Начнем с простого примера.

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

func() // Window

Для сложного примера внешняя externalFunc имеет запутанную цель.

function outerFunc() {
  console.log(this) // { x: 1 }

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

  func()
}

outerFunc.bind({ x: 1 })()

7. Не в функции

Сценарии, которых нет в функции, можно разделить на сценарии браузера.<script />теги или в файлах модулей Node.js.

  1. существует<script />В теге это указывает на Window.
  2. В файлах модулей Node.js это указывает на объект экспорта модуля по умолчанию, который называется module.exports.

нестрогий режим

Строгий режим был введен в ES5. До спецификации ES5 в нестрогом режиме это не могло быть неопределенным или нулевым. Таким образом, ** в нестрогом режиме с помощью приведенной выше семиступенчатой ​​формулы, если будет сделан вывод, что this указывает на undefined или null, то это будет указывать на глобальный объект. ** Глобальным объектом является Window в среде браузера и Global в среде Node.js.

Например, в следующем коде в нестрогом режиме this относится к глобальному объекту.

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()

Результат выполнения в нестрогом режиме:非严格模式下-this-为-nullish.png

В строгом режиме выполните тот же код для сравнения. Не забудьте скопировать и вставить весь код в консоль сразу для запуска в строгом режиме (поскольку первая строка «использовать строгий» будет действовать только для следующего кода).

"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()

Результат выполнения в строгом режиме:严格模式下-this-为-nullish.png

Формула из семи шагов завершена как в строгом, так и в нестрогом режиме, за исключением того, что в нестрогом режиме значение null или undefined будет преобразовано в глобальный объект. Поэтому я не указала это в рецепте.

рассмотрение

Сначала произнесите формулу, а затем задайте вопрос: «Функция стрелки, новая, связать, применить и вызвать, точка Оби (объект), прямой вызов, а не в функции».

1. Каково значение func.count после выполнения следующего кода?

function func(num) {
  this.count++
}

func.count = 0
func(1)

Отвечать

Значение func.count равно 0.

В соответствии с формулами,func()При вызове относится к категории 6 "прямой вызов". В нестрогом режимеthisУказывает на глобальный объект.thisЭто вообще не имеет ничего общего с func, так чтоfunc.countпостоянный. так легко.

2. На кого это указывает в следующей стрелочной функции?

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" })()

Отвечать

// obj
// undefined
// newObj
// undefined
// bindObj

Разве это не очень просто, вы потеряли учебу?

Если узнаешь, ставь лайк и подписывайся~

Если вы еще этого не изучили, поставьте лайк этой статье и прочитайте ее несколько раз~

Если у вас есть вопросы, пишите в комментарии~