Всего 3 минуты для JavaScript «Это»
JavaScript this
раздражает и вызывает некоторые проблемы, которые сложно исследовать.
Я прочитал много статей о JavaScript this
и нашел самый быстрый способ его понять.
Контрольный опрос
Сможете ответить на выход 2 звонка?
var obj = { showThis: function(){ console.log(this) } }
var a = obj.showThis obj.showThis() // this is obj a() // this is window
Если вы не понимаете поведения здесь. Эта статья может помочь.
Как вызывалась функция Javascript
В ES6 есть 3 способа вызова функции.
func(a1, a2)
obj.child.method(a1, a2)
func.call(context, a1, a2)
Фактически, первые 2 метода можно преобразовать в 3-й.
//func(a1, a2) func.call(undefined, a1, a2)
//obj.child.method(a1, a2) obj.child.method.call(obj.child, a1, a2)
Нам нужно только помнить func.call(context, a1, a2)
.
И this
- это context
в аргументах.
Давай еще раз посмотрим викторину
Прямой вызов функции
var obj = { showThis: function(){ console.log(this) } }
var a = obj.showThis a.call(undefined) //a() //output: window
Но мы получили window
not undefined, почему? Поскольку в браузере существует правило, согласно которому, если контекст имеет значение null или undefined, контекстом по умолчанию является окно. (в строгом режиме вывод будет неопределенным)
Если вы хотите получить объект из этого, вы можете написать так:
var obj = { showThis: function(){ console.log(this) } }
var a = obj.showThis a.call(obj) //output: obj
Вызов метода объекта
Метод мог конвертировать:
var obj = { showThis: function(){ console.log(this) } }
//obj.showThis() obj.showThis.call(obj) //output: obj
В настоящее время this
= контекст, поэтому this
- это obj
.
Функция стрелки
Самый простой способ запомнить this
в стрелочной функции - это то, что в стрелочной функции не создается новый this
.
this
в стрелочной функции равно this
снаружи.
function foo() { setTimeout(() => { console.log('id:', this.id); }, 100) }
var id = 21
foo.call({ id: 42 }) // id: 42
В global this
= window, в функции foo this
= {id:42}
.
Функция стрелки находится внутри foo()
, поэтому функция стрелки this
= {id:42}
.
Если вы измените функцию стрелки на обычную функцию, результатом foo.call({ id: 42 })
будет 21. Это потому, что var id = 21
на самом деле window.id
, поскольку оно объявлено на верхнем уровне, а this
будет относиться к window
, поскольку контекст не передается во вложенный function
.
Как заставить ценность этого
Мы можем использовать apply / call / bind, чтобы принудительно установить значение this
.
var a = { name : "Cherry", func1: function () { console.log(this.name) }, func2: function () { setTimeout( function () { this.func1() }.apply(a),100); } }; a.func2() // Cherry
var a = { name : "Cherry", func1: function () { console.log(this.name) }, func2: function () { setTimeout( function () { this.func1() }.call(a),100); } }; a.func2() // Cherry
var a = { name : "Cherry", func1: function () { console.log(this.name) }, func2: function () { setTimeout( function () { this.func1() }.bind(a)(),100); } }; a.func2() // Cherry
Вот и все! Вы можете преобразовать вызов метода или функции в func.call()
, чтобы убедиться в этом. Надеюсь это поможет!