Постараюсь дать простое объяснение (без всяких асинхронных функций), когда конструкция self = this применяется в JavaScript.
Создадим объект, в котором определены поле a = 2, b = 3 и функция fn, которая выводит в консоль поле a данного объекта при помощи ключевого слова this. В консоли мы ожидаемо получаем поле a объекта myObj, то есть 2.
var myObj = {
a : 2,
b : 3,
fn : function(){
console.log(this.a) // 2
}
}
myObj.fn()
Но если внутрь функции fn вложить ещё одну функцию и в ней в консоль попытаться вывести поле b объекта myObj, мы получим в этом случае undefined.
var myObj = {
a : 2,
b : 3,
fn : function(){
console.log(this.a) // 2
var fn2 = function(){
console.log(this.b) // undefined
}
fn2()
}
}
myObj.fn()
Дело в том что, проверяется контекст функции, в которой встретилось ключевое слово this. В данном случае это функция fn2. Её контекст (ближайшие внешние фигурные скобки) относится к функции, а не к какому-либо объекту. И поэтому ключевое слово this в этом случае указывает на глобальный объект window. У объекта window нет поля b и в консоли мы получим undefined.
Но всё решает конструкция self = this. Вставляем эту конструкцию, меняем this.b на self.b И в консоли получаем 2 и 3.
var myObj = {
a : 2,
b : 3,
fn : function(){
self = this
console.log(this.a) // 2
var fn2 = function(){
console.log(self.b) // 3
}
fn2()
}
}
myObj.fn()
В данном случае ключевое слово this встречается в функции fn, контекстом которой является объект myObj. И поэтому this указывает на этот объект. И переменной self присваивается ссылка на объект myObj. Ну а функции fn2 доступна переменная self, потому что она находится в её контексте. Таким образом, вместо self подставляется ссылка на объект myObj и в консоли мы получаем желаемые 2 и 3.