Русский
Русский
English
Статистика
Реклама

Из песочницы Коротко о this в функциях javascript

Предисловие


На просторах интернета довольно много информации о том, как работает this, но мне всё время не хватало буквально чуть-чуть, чтобы до конца в этом разобраться.

Недавно я все же, как мне кажется, сделал это и хотел бы поделиться с вами.

Без лишних слов


Мы разберем как простые, так и сложные примеры так что всем будет интересно.

Два основных тезиса, которые мы рассмотрим:

(1) Для функций, объявленных через function(){}, this вычисляется в момент вызова.
(2) Для стрелочных функций this определяется в момент создания функции.

Начнем с простых примеров.

function globalFunc() {  console.log(this);}const globalArrowFunc = () => {  // создали функцию в глобальной области видимости, где this - window/undefind  // мы будем полагать, что включен use strict и глобально this === undefind  console.log(this);}globalFunc(); // undefindglobalArrowFunc(); // 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 - undefinddog.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
К списку статей
Опубликовано: 16.08.2020 20:19:14
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Javascript

Javascript this

Стрелочные функции

Функции в javascript

Контекст javascript

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru