Поверьте мне, если вы запомните 7️⃣ шагов из этой статьи, вы сможете полностью понять указатель this в JS.
Сначала прочтите формулу: стрелочные функции, новые, привязка, применение и вызов, объект, прямой вызов, а не в функции.
По порядку формул, пока выполняется один из предыдущих сценариев, можно определить, что это указывает на.
Далее они будут подробно объяснены в порядке формул.Примеры кодов в этой статье выполняются в консоли консоли Chrome.
В конце статьи есть хорошо подготовленные практические вопросы для проверки результатов обучения, не забудьте попробовать~
1. Стрелочные функции
Стрелочная функция идет первой, потому что это не будет изменено, поэтому, пока текущая функция является стрелочной, нет необходимости смотреть на другие правила.
this стрелочной функции — это указатель на внешнее this при его создании. Здесь есть два важных момента:
- При создании стрелочных функций, уже установлено, на что это указывает.
- это внутри функции стрелки указывает навнешнее это.
Таким образом, чтобы узнать this функции стрелки, вы должны сначала узнать точку внешнего this, и вам нужно продолжать применять формулу из семи шагов во внешнем слое.
2. new
При вызове функции с новым ключевым словом this в функции должен быть новым объектом, созданным JS.
Читатели могут задаться вопросом: «Если стрелочная функция вызывается с новой клавишей, будет ли изменена this стрелочной функции?».
Попробуем на консоли.
func = () => {}
new func() // throw error
Как видно из консоли, стрелочные функции нельзя использовать в качестве конструкторов, поэтому их нельзя выполнять с помощью 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.
- существует
<script />
В теге это указывает на Window. - В файлах модулей 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()
Результат выполнения в нестрогом режиме:
В строгом режиме выполните тот же код для сравнения. Не забудьте скопировать и вставить весь код в консоль сразу для запуска в строгом режиме (поскольку первая строка «использовать строгий» будет действовать только для следующего кода).
"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()
Результат выполнения в строгом режиме:
Формула из семи шагов завершена как в строгом, так и в нестрогом режиме, за исключением того, что в нестрогом режиме значение 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
Разве это не очень просто, вы потеряли учебу?
Если узнаешь, ставь лайк и подписывайся~
Если вы еще этого не изучили, поставьте лайк этой статье и прочитайте ее несколько раз~
Если у вас есть вопросы, пишите в комментарии~