Понимаем JS идиому var self = this: использование и цель
Быстрый ответ
Идиоматическое выражение var self = this;
используется в JavaScript для сохранения изначального контекста this
в коллбеках и внутренних функциях, в которых этот контекст может оказаться изменённым или искажённым. Это своего рода защитный механизм, обеспечивающий стабильность доступа к свойствам и методам первоначального объекта.
Пример:
function Widget() {
var self = this; // 'self' обеспечивает постоянство контекста 'this'
self.number = 42; // 'self' сохраняет за собой число 42
document.addEventListener('click', function() {
console.log(self.number); // 'self' позволяет обращаться к number, даже внутри коллбека
});
}
Подробный разбор: 'this' и его свойства
В JavaScript ключевое слово this
меняет свой контекст в зависимости от места и способа выполнения функции. Так, например, в обработчиках событий this
связан с элементом, инициировавшим событие, а не с исходным объектом. Выражение var self = this;
создаёт замыкание, позволяя сохранить изначальный контекст this
во внутренних функциях.
Возможные конфликты имен: 'self' и 'window.self'
Использование имени self
для переменной может вызвать нежелательные эффекты из-за совпадения имени с window.self
в браузерском JavaScript, которое всегда ссылается на объект window
. По этой причине использование альтернативных имён, наподобие var that = this;
или var _this = this;
, может быть более предпочтительным.
Вклад ES6: стрелочные функции
Введение стрелочных функций в стандарт ES6 значительно упростило работу с контекстом this
. Ведь стрелочные функции автоматически принимают this
из окружающей области видимости, что во многих случаях исключает потребность в дополнительных переменных.
function Widget() {
this.number = 42; // Это особое число – ответ на главный вопрос жизни, Вселенной и всего прочего
document.addEventListener('click', () => {
console.log(this.number); // Стрелочные функции надёжно сохраняют исходный 'this'
});
}
Уверенное управление контекстом: методы Apply и Call
Методы Function.prototype.apply()
и Function.prototype.call()
предоставляют возможность явно задать контекст this
для функции, что является прямым и недвусмысленным способом вызова функции.
Помощь со стороны jQuery: метод '.proxy()'
Пользователи jQuery могут также рассмотреть использование метода .proxy()
, который элегантно управляет контекстом функции, пряча сложности управления контекстом за простым интерфейсом.
Замыкание: в глубину 'self = this;'
Замыкание — это особенность JavaScript, которая позволяет ему сохранять переменные из локальной области видимости функции, даже после её выполнения. Замыкание делает var self = this;
своеобразной временной капсулой, которая захватывает текущий контекст для дальнейшего использования.
Событийно-ориентированное программирование: 'self' в помощь
В событийно-ориентированном программировании self = this;
играет важную роль, позволяя обработчикам событий сохранить ссылку на изначальный объект, а не на инициатора события. Это способствует более интуитивно понятному поведению this
.
Цель: доступный и поддерживаемый код
Выбирая один из способов работы с контекстом, следует обращать внимание на доступность и удобство поддержки кода и руководствоваться современными лучшими практиками.
Визуализация
Проиллюстрируем использование var self = this;
на примере поведения временных зон.
Домашний офис (🏠): "Время по местным часам, прямо сейчас! ⏰"
Главный офис (🏢): "ОК, примем в работу время домашнего офиса!"
Офис передает текущее местное время (this
) на глобальные часы 'Self':
var self = this; // 🏠⏰ ➡️🌐⏰ Часы 'Self' теперь синхронизируются с домашним офисом
В день запуска, когда все окружающие заняты своими делами:
День запуска (🚀): "Стоп! Какая сейчас по счёту минута?"
Self (🌐⏰): "Следует не переживать! У меня сохранено местное время домашнего офиса! 📢"
'Благодаря 'Self', несмотря на разброс местного времени, все действия происходят в синхронизации с внутренними процессами домашнего офиса. 🌎➡️🏠⏰➡️🌐⏰➡️⌚
Управление 'this' в мире асинхронного программирования
В мире асинхронного программирования на JavaScript контроль над 'this' становится весьма критичным, особенно при работе с промисами или async/await. Применение self = this
или стрелочных функций обеспечивает надёжную защиту `this' от несанкционированных изменений и позволяет воспроизводить его исходный контекст.
Классические концепции в новой обёртке: поля классов ES6
Несмотря на то, что подход self = this
может восприниматься как устаревший, современный JavaScript предлагает эффективные альтернативы, такие как поля классов и стрелочные функции в классах, способствующие более прозрачному и явному управлению контекстом:
class Widget {
number = 42;
handleClick = () => {
console.log(this.number); // современный способ контроля над 'this' в классах
};
}
Завершение: Овладеваем 'this'
Понимание работы this
— важнейший элемент в процессе создания надёжных приложений на JavaScript. Все знают о его подводных камнях. Осознание поведения и свойств this
позволяет разработчикам предотвратить неожиданные изменения контекста и значительно повысить устойчивость кода.