[JavaScript] Коротко о this в функциях javascript
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
Предисловие
На просторах интернета довольно много информации о том, как работает this, но мне всё время не хватало буквально чуть-чуть, чтобы до конца в этом разобраться.
Недавно я все же, как мне кажется, сделал это и хотел бы поделиться с вами.
Без лишних слов
Мы разберем как простые, так и сложные примеры — так что всем будет интересно.
Два основных тезиса, которые мы рассмотрим:
(1) Для функций, объявленных через function(){}, this вычисляется в момент вызова.
(2) Для стрелочных функций this определяется в момент создания функции.
Начнем с простых примеров.
function globalFunc() {
console.log(this);
}
const globalArrowFunc = () => {
// создали функцию в глобальной области видимости, где this - window/undefind
// мы будем полагать, что включен use strict и глобально this === undefind
console.log(this);
}
globalFunc(); // undefind
globalArrowFunc(); // undefind
А что, если мы добавим эти функции в объекта:
const cat = {
name: 'Pirate',
globalFunc,
globalArrowFunc
};
cat.globalFunc(); // { name: 'Pirate', ... }
cat.globalArrowFunc(); // undefind
Давайте разберемся.
Вызов cat.globalFunc() вернул нам объект cat. Для простоты понимания, можно рассматривать это так «this, при вызове функций, объявленных через function(){}, будет равен объекту перед точкой».
Тогда почему cat.globalArrowFunc() вернул нам undefind? Дело в том, что значение this для стрелочной функции определяется в момент ее создания, а, когда мы ее создавали, значение this было undefind.
Теперь давайте создадим объект с парой методов:
const dog = {
name: 'Viking',
// для наглядности мы не будем использовать сокращенный синтаксис
// но с ним было бы тоже самое
localFunc: function() {
console.log(this);
},
localArrowFunc: () => {
console.log(this);
}
};
dog.localFunc(); // { name: 'Viking', ... }
dog.localArrowFunc(); // undefind
Почему так?
dog.localFunc() — потому что объект перед точкой dog.
dog.localArrowFunc() — потому что внутри объекта this — это тоже глобальный объект, а значит мы получаем undefind.
Давайте немного усложним наш пример.
const dog = {
name: 'Viking',
localFunc: function() {
const arrowFuncInLocalFunc = () => {
console.log(this);
};
function funcInLocalFunc() {
console.log(this);
};
arrowFuncInLocalFunc(); // 1
funcInLocalFunc(); // 2
},
localArrowFunc: () => {
const arrowFuncInLocalArrowFunc = () => {
console.log(this);
};
function funcInLocalArrowFunc() {
console.log(this);
};
arrowFuncInLocalArrowFunc(); // 3
funcInLocalArrowFunc(); // 4
}
};
dog.localFunc();
// 1 - { name: 'Viking', ... }
// 2 - undefind
dog.localArrowFunc();
// 3 - undefind
// 4 - undefind
Давайте разбираться!
(1) arrowFuncInLocalFunc() // { name: 'Viking',… }
Почему так происходит?
Потому что, когда мы создавали объект, мы записали ему функцию localFunc. А, как мы помним из предыдущих примеров, для нее this — это объект перед точкой, то есть { name: 'Viking',… }. Теперь поговорим про саму функцию arrowFuncInLocalFunc — она создается непосредственно в момент вызова localFunc и запоминает значение this, которое было в месте ее создания. Таким образом мы получаем, что arrowFuncInLocalFunc возвращает нам { name: 'Viking',… }.
(2) funcInLocalFunc() // undefind
Почему так происходит?
Как мы говорили ранее, для функций, объявленных через function(){} значение this определяется в момент вызова и равно объекту перед точкой. В данном случае у нас нет объекта перед точкой, а значит this — глобальный объект или, в нашем случае, undefind.
(3) arrowFuncInLocalArrowFunc() // undefind
Почему так происходит?
Этот пример очень похож на (1), только наша функция arrowFuncInLocalArrowFunc создается внутри такой же стрелочной функции. Также мы помним, что стрелочные фукнции в момент объявления записывают в this значение из своего окружения. Однако, наша функция была создана внутри localArrowFunc, для которой this — undefind. А значит и для arrowFuncInLocalArrowFunc this будет равен undefind.
(4) funcInLocalArrowFunc() // undefind
Почему так происходит?
Точно по той же причине, что и в пункте (2) для funcInLocalFunc
Давайте рассмотрим еще один пример:
const cat = {
name: 'Tom',
getFuncWithTimName: function() {
return () => {
console.log(this.name);
}
}
};
const mouse = {
name: 'Jerry',
logName: cat.getFuncWithTimName()
};
mouse.logName(); // Tom o_O !?
Так происходит потому что getFuncWithTimName создает и возвращает стрелочную функцию, а в момент создания стрелочной функции this тот же самый, что и у getFuncWithTimName. А для getFuncWithTimName this — это объект перед точкой (cat).
Итого
Контекст для стрелочных функци определяется в момент их создания.
Контекст для function(){} определяется в момент их вызова и равен объекту перед точкой.
===========
Источник:
habr.com
===========
Похожие новости:
- [Разработка веб-сайтов, JavaScript] Веб-компоненты в реальном мире (часть 2)
- [JavaScript] LINQ на JavaScript для самых маленьких
- [Разработка веб-сайтов, JavaScript, Программирование, Node.JS] Краткое руководство по Node.js для начинающих (SPA, PWA, mobile-first)
- [Разработка веб-сайтов, JavaScript, Java, VueJS] Знакомство с Vuecket
- [JavaScript, Node.JS, ReactJS, VueJS] Что, черт возьми, такое гидратация и регидратация? (перевод)
- [Разработка веб-сайтов, JavaScript, Программирование] JavaScript: 250+ практических вопроса (список + викторина + бонус)
- [Разработка веб-сайтов, JavaScript, Программирование] Webpack: руководство для начинающих (перевод)
- [Разработка веб-сайтов, JavaScript] Влияние service worker'ов на web-приложения
- [JavaScript, Java, Big Data, Data Engineering] В диких условиях. Итоги проектов Школы программистов в эпоху самоизоляции
- [Разработка веб-сайтов, JavaScript, Node.JS] Архитектура современных корпоративных Node.js-приложений
Теги для поиска: #_javascript, #_javascript_this, #_strelochnye_funktsii (стрелочные функции), #_funktsii_v_javascript (функции в javascript), #_javascript, #_kontekst_javascript (контекст javascript), #_javascript
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:18
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
Предисловие На просторах интернета довольно много информации о том, как работает this, но мне всё время не хватало буквально чуть-чуть, чтобы до конца в этом разобраться. Недавно я все же, как мне кажется, сделал это и хотел бы поделиться с вами. Без лишних слов Мы разберем как простые, так и сложные примеры — так что всем будет интересно. Два основных тезиса, которые мы рассмотрим: (1) Для функций, объявленных через function(){}, this вычисляется в момент вызова. (2) Для стрелочных функций this определяется в момент создания функции. Начнем с простых примеров. function globalFunc() {
console.log(this); } const globalArrowFunc = () => { // создали функцию в глобальной области видимости, где this - window/undefind // мы будем полагать, что включен use strict и глобально this === undefind console.log(this); } globalFunc(); // undefind globalArrowFunc(); // undefind А что, если мы добавим эти функции в объекта: const cat = {
name: 'Pirate', globalFunc, globalArrowFunc }; cat.globalFunc(); // { name: 'Pirate', ... } cat.globalArrowFunc(); // undefind Давайте разберемся. Вызов cat.globalFunc() вернул нам объект cat. Для простоты понимания, можно рассматривать это так «this, при вызове функций, объявленных через function(){}, будет равен объекту перед точкой». Тогда почему cat.globalArrowFunc() вернул нам undefind? Дело в том, что значение this для стрелочной функции определяется в момент ее создания, а, когда мы ее создавали, значение this было undefind. Теперь давайте создадим объект с парой методов: const dog = {
name: 'Viking', // для наглядности мы не будем использовать сокращенный синтаксис // но с ним было бы тоже самое localFunc: function() { console.log(this); }, localArrowFunc: () => { console.log(this); } }; dog.localFunc(); // { name: 'Viking', ... } dog.localArrowFunc(); // undefind Почему так? dog.localFunc() — потому что объект перед точкой dog. dog.localArrowFunc() — потому что внутри объекта this — это тоже глобальный объект, а значит мы получаем undefind. Давайте немного усложним наш пример. const dog = {
name: 'Viking', localFunc: function() { const arrowFuncInLocalFunc = () => { console.log(this); }; function funcInLocalFunc() { console.log(this); }; arrowFuncInLocalFunc(); // 1 funcInLocalFunc(); // 2 }, localArrowFunc: () => { const arrowFuncInLocalArrowFunc = () => { console.log(this); }; function funcInLocalArrowFunc() { console.log(this); }; arrowFuncInLocalArrowFunc(); // 3 funcInLocalArrowFunc(); // 4 } }; dog.localFunc(); // 1 - { name: 'Viking', ... } // 2 - undefind dog.localArrowFunc(); // 3 - undefind // 4 - undefind Давайте разбираться! (1) arrowFuncInLocalFunc() // { name: 'Viking',… } Почему так происходит? Потому что, когда мы создавали объект, мы записали ему функцию localFunc. А, как мы помним из предыдущих примеров, для нее this — это объект перед точкой, то есть { name: 'Viking',… }. Теперь поговорим про саму функцию arrowFuncInLocalFunc — она создается непосредственно в момент вызова localFunc и запоминает значение this, которое было в месте ее создания. Таким образом мы получаем, что arrowFuncInLocalFunc возвращает нам { name: 'Viking',… }. (2) funcInLocalFunc() // undefind Почему так происходит? Как мы говорили ранее, для функций, объявленных через function(){} значение this определяется в момент вызова и равно объекту перед точкой. В данном случае у нас нет объекта перед точкой, а значит this — глобальный объект или, в нашем случае, undefind. (3) arrowFuncInLocalArrowFunc() // undefind Почему так происходит? Этот пример очень похож на (1), только наша функция arrowFuncInLocalArrowFunc создается внутри такой же стрелочной функции. Также мы помним, что стрелочные фукнции в момент объявления записывают в this значение из своего окружения. Однако, наша функция была создана внутри localArrowFunc, для которой this — undefind. А значит и для arrowFuncInLocalArrowFunc this будет равен undefind. (4) funcInLocalArrowFunc() // undefind Почему так происходит? Точно по той же причине, что и в пункте (2) для funcInLocalFunc Давайте рассмотрим еще один пример: const cat = {
name: 'Tom', getFuncWithTimName: function() { return () => { console.log(this.name); } } }; const mouse = { name: 'Jerry', logName: cat.getFuncWithTimName() }; mouse.logName(); // Tom o_O !? Так происходит потому что getFuncWithTimName создает и возвращает стрелочную функцию, а в момент создания стрелочной функции this тот же самый, что и у getFuncWithTimName. А для getFuncWithTimName this — это объект перед точкой (cat). Итого Контекст для стрелочных функци определяется в момент их создания. Контекст для function(){} определяется в момент их вызова и равен объекту перед точкой. =========== Источник: habr.com =========== Похожие новости:
|
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 16:18
Часовой пояс: UTC + 5