Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   По области видимости function declaration (https://javascript.ru/forum/misc/83614-po-oblasti-vidimosti-function-declaration.html)

micscr 25.01.2022 15:33

По области видимости function declaration
 
Приветствую.
Хотел уточнить, как точно определяется доступность функций, объявленных просто как function имя(){}
вот, в примере:
function try1(){
  //hoisted(); //ошибка (1)
  {
    //hoisted(); // выводит "foo" (2)
    function hoisted() {
      console.log("foo");
    }
  }
  hoisted(); // выводит "foo" (3)
}
try1();

- поднятие функции получается доступно в блоке кода (2)
- но при этом сама функция доступна и за пределами этого блока (после него) (3)
- а "до" (1) нельзя

Может где есть описание, как точно такое определение делается.

Так само и с условным определением функций, то что я раньше выписывал себе из документации, смотрю не так сейчас работает

MallSerg 25.01.2022 16:08

Гугли в сторону "Временная мёртвая зона" ES6.

voraa 25.01.2022 22:02

Нет, к TDZ это отношения не имеет.
Это FiB (так иногда обозначается - Function in Вlock).

Это отдельная тема, которая описана в приложении к спецификации.
https://262.ecma-international.org/9...lity-semantics

Там, в частности, говорится, что до ES2015 это вообще никак не регламентировалось, и реализации в разных браузерах могли по-разному рассматривать этот случай.

Rise 26.01.2022 10:47

micscr,
Надо писать в строгом режиме - 'use strict'. Он для этого и создан - ограничивать старое поведение. Например, классы и модули в нем работают по-умолчанию, потому что это новые сущности. В местном учебнике это доходчиво описано - 1 и 2, и в любой непонятной ситуации можешь просто читать учебник, он постоянно обновляется, в нем достаточно актуальная информация.

micscr 26.01.2022 14:23

Rise, а в указанных вами статьях не говорится как строгий режим касается моей ситуации.
Так определять функции как в примере я и не собирался, но мало ли, встречу где..., постоянно ведь с чужим кодом

Rise 26.01.2022 15:24

micscr,
Там говорится про современный js. Современный js это ES6+. В старой версии js, ES5, блоки кода не имели свою область видимости.

Отличия ES6 от ES5 можешь почитать здесь.

voraa 26.01.2022 20:33

Цитата:

Сообщение от Rise
В старой версии js, ES5, блоки кода не имели свою область видимости.

Отличия ES6 от ES5 можешь почитать здесь.

Вот ничего там не написано, про случай и пример micscr
Там говорится
Цитата:

are hoisted: independently of where a function declaration is mentioned in its scope, it is always created at the beginning of the scope.
Т.е
Цитата:

независимо от того, где объявление функции упоминается в ее области видимости, она всегда создается в начале области видимости.
Посмотрим на пример micscr.
В какой области видимости объявлена функция hoisted?
Если в области блока, то она поднимается в начало блока и работает случай (2). А почему тогда работает (3)?
Если она в области функции try1, почему не работает (1)?

voraa 26.01.2022 20:47

Вот тут есть отрывок и с книги
Симпсон К
{Вы пока еще не знаете JS} Область видимости и замыкания.
https://habr.com/ru/company/piter/blog/587888/
Где все объяснено предельно просто
Цитата:

Спецификация JS гласит, что объявления функций внутри блоков имеют блоковую область видимости, .... Однако большинство браузерных ядер JS (включая движок v8, который происходит от Chrome, но также используется в Node) ведет себя в соответствии с пунктом (2); это означает, что идентификатор имеет область видимости вне блока if, но значение-функция не инициализируется автоматически, поэтому оно остается равным undefined.

Почему браузерным движкам JS разрешается нарушать своим поведением спецификацию? Потому что эти движки уже обладали поведением, связанным с FiB, до появления блоковой видимости в ES6, и существовали опасения, что изменения, направленные на соответствие спецификации, могут нарушить работоспособность существующего кода JS веб-сайтов. Из-за этого в приложении B спецификации JS было сделано исключение, позволяющее некоторые отклонения для браузерных движков JS (и только!).
Потому, что так сделано!

Rise 27.01.2022 00:21

Цитата:

Сообщение от voraa
Если она в области функции try1, почему не работает (1)?

Потому что в ES5 самостоятельных блоков кода не было. Поэтому для обратной совместимости он рассматривается как что-то типа:
function try1(){
  //hoisted(); //ошибка (1)
  if (true) {
    //hoisted(); // выводит "foo" (2)
    function hoisted() {
      console.log("foo");
    }
  }
  hoisted(); // выводит "foo" (3)
}
try1();

Цитата:

Сообщение от voraa
там не написано, про случай и пример micscr

Вы всё ждете с micscr, что вам распишут все миллиард возможных примеров что-ли... Какой смысл придумывать пример, который и раньше то никто так не писал. Ни разу не встречал в старом коде декларацию функций в условных операторах. Даже старый строгий режим запрещал это делать. Это как запланировать встретить динозавра в реальном мире.

micscr 27.01.2022 07:12

Цитата:

Сообщение от voraa (Сообщение 543311)
А почему тогда работает (3)?

С 'use strict' не работает (3).

Но все равно не все четко.

Вот в доках, сказано что

Вызовет ошибку.
Объявление функций в блоках if (a < b) { function f() {} }

, а (2) работает и со строгим режимом


Часовой пояс GMT +3, время: 00:04.