Ответ
this в JavaScript указывает на контекст выполнения функции. Его значение зависит от того, как функция вызывается:
-
Глобальный контекст:
Вне функцийthisссылается на глобальный объект (windowв браузере,globalв Node.js). -
Метод объекта:
В методе объектаthisссылается на сам объект.
const obj = {
name: 'Test',
greet() { console.log(this.name); }
};
obj.greet(); // 'Test'
- Обычная функция:
В строгом режиме ('use strict')thisбудетundefined, иначе — глобальный объект.
function test() { console.log(this); }
test(); // window (или undefined в strict mode)
- Стрелочная функция:
Не имеет своегоthis, берет его из внешнего контекста.
const obj = {
name: 'Test',
greet: () => console.log(this.name) // this — внешний контекст (например, window)
};
obj.greet(); // undefined (если нет name в глобальном объекте)
- Явное указание:
Можно привязать контекст с помощьюcall,applyилиbind.
function greet() { console.log(this.name); }
greet.call({ name: 'Alice' }); // 'Alice'
Контекст this определяется в момент вызова функции, а не её объявления.
Ответ 18+ 🔞
А, этот ваш this в JavaScript, ну просто пиздец, а не тема! Сидит себе такая переменная-невидимка, и значение у неё меняется, как перчатки у мартышлюшки — в зависимости от того, кто и как её позвал. Сейчас разберём, но держись, а то мозг сломаешь.
Смотри, представь, что this — это такой хамелеон, блядь. Он не сам по себе, он всегда про то, кто его вызвал. Не где объявили, а кто в данный момент на кнопку «пуск» нажал!
1. Глобально, на весь мир.
Если ты просто в коде, вне всяких функций, напишешь console.log(this), то в браузере он тебе глобальный объект window и покажет. Типа «я тут главный, на всё смотрю». В Node.js будет global. Просто, да? А вот хуй там, дальше начинается.
2. Метод у объекта.
Тут вроде логично. Если функция — это метод объекта (прилепилась к нему, как банный лист), то this внутри неё — это сам объект. Как будто она говорит: «Я работаю на этого дядю».
const мужик = {
имя: 'Василий',
представиться() {
console.log(`Меня зовут ${this.имя}, ёпта!`);
}
};
мужик.представиться(); // Выведет: "Меня зовут Василий, ёпта!"
Всё чётко. this — это мужик.
3. Обычная функция-одиночка. А вот тут уже начинается пиздец. Берём ту же функцию, но выдернем её из объекта и вызовем просто так.
function скажиПривет() {
console.log(this);
}
скажиПривет(); // Что будет? А хер его знает!
Если у тебя включен строгий режим ('use strict'), то будет undefined. А если нет — опять этот всеобщий window полезет. Потому что функция теперь ни к кому не привязана, она сама по себе, и контекст потерялся. Вот так вот, блядь.
4. Стрелочная функция — хитрая жопа.
Вот это вообще отдельная песня. Стрелочная функция — она как ребёнок, у неё своего this нет вообще, в рот меня чих-пых! Она его берёт у родителя, из того места, где её объявили. Смотри:
const мужик = {
имя: 'Василий',
представиться: () => {
console.log(`Меня зовут ${this.имя}`); // this — НЕ мужик!
}
};
мужик.представиться(); // Выведет: "Меня зовут undefined"
Почему? Потому что стрелочная функция была создана в глобальной области, вот её this и есть глобальный объект (window), у которого поля имя нет. Она контекст не переопределяет, в отличие от обычной функции. Запомни это, а то обосрёшься на собеседовании.
5. Явное указание — «ты будешь вот этим!».
А если нам надо, чтобы функция работала с тем контекстом, который мы ей скажем? Вот тут на помощь приходят три брата-насильника: call, apply и bind. Ими ты можешь явно сказать: «Слушай сюда, сука, в этой функции this будет вот этот объект!».
function поздоровайся() {
console.log(`Привет от ${this.титул}!`);
}
const король = { титул: 'Король Артур' };
const палач = { титул: 'Палач Боб' };
// call — вызывает сразу, передавая контекст и аргументы через запятую
поздоровайся.call(король); // Привет от Король Артур!
// apply — то же самое, но аргументы массивом
поздоровайся.apply(палач); // Привет от Палач Боб!
// bind — не вызывает, а возвращает новую функцию, намертво привязанную к контексту
const поздоровайсяОтКороля = поздоровайся.bind(король);
поздоровайсяОтКороля(); // Привет от Король Артур!
Вот и весь сказ, блядь. Главное правило, которое выжги себе на подкорке: this определяется не там, где функцию написали, а там, где её ВЫЗВАЛИ. Как позвали, так и ответит. То ли объектом, то ли undefined, то ли глобальным window.
Поначалу мозг вытекает, но потом привыкаешь. А если нет — ну, бывает, не всем дано. Главное — стрелочные функции не используй как методы объектов, если тебе нужен доступ к самому объекту через this. И всё будет пучком.