Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   Почему блок не изолирует функцию (https://javascript.ru/forum/misc/83051-pochemu-blok-ne-izoliruet-funkciyu.html)

lgick 02.09.2021 13:20

Почему блок не изолирует функцию
 
В замыканиях есть задача,
в блоке if {} указана декларативная функция, которая судя по ответу не работает, но по факту это не так

let phrase = "Hello";

if (true) {
  let user = "John";

  function sayHi() {
    alert(`${phrase}, ${user}`);
  }
}

sayHi(); // будет выполнена



Почему?

voraa 02.09.2021 13:58

Блочная область видимости может быть только у переменных, объявленных через let или const.
У переменных объявленных через var или у функций заданных через function областью видимости глобальная или вся функция, где они объявлены
Вот так
const sayHi = function () {
    alert(`${phrase}, ${user}`);
  }

Будет только в блоке.

lgick 02.09.2021 16:01

странно почему так происходит, ведь блок кода в {} должен быть изолирован. Поэтому появились const и let и устарел var

Также в учебнике конструкция IIFE :

(function () {
...
}())


считается устаревшей
ведь появилось лексическое окружение в блоке кода,
но оно работает не всегда и может создавать ошибки:

let a = 1
function x() {
   return 1
}

{
  let a = 2
  function x() {
      return 2
  }
}

alert(a) // по прежнему 1
alert(x()) // неожиданно 2



выходит для инкапсуляции без IIFE не обойтись?

Alexandroppolus 02.09.2021 16:52

Цитата:

Сообщение от lgick
судя по ответу не работает

Косяк в учебнике. Наверняка о нем есть тут пару слов - https://github.com/javascript-tutori...pt.info/issues (или в английской версии)
Цитата:

Сообщение от lgick
выходит для инкапсуляции без IIFE не обойтись?

Да.
Возможно, имеется в виду, что всякие вебпаки и тому подобное делают такое обертывание сами. В рабочих проектах не приходится писать IIFE, кругом один сплошной import/export, который переделывается сборщиком.

lgick 02.09.2021 17:07

это работает правильно в строгом режиме

'use strict'
let a = 1
function x() {
   return 1
}

{
  let a = 2
  function x() {
      return 2
  }
}

alert(a) // по прежнему 1
alert(x()) // ожидаемо 1

voraa 02.09.2021 18:11

Цитата:

Сообщение от lgick
выходит для инкапсуляции без IIFE не обойтись?

Объявлять функции через const и никаких проблем.
А те же стрелочные по другому и не объявить.

Aetae 03.09.2021 03:42

В нестрогом режиме оно не работает по причинам обратной совместимости, очевидно. Если просто взять и выкатить такую хрень без доп. модификаторов - это сломает половину интернета.
И идея с "use strict" тож такая себе. Сейчас это сработвло. Но когда через N лет опять надо будет что-то ломающее добавить, придётся вводить "use super strict" или типа того.)

voraa, бесят меня "объявлтели стрелочек через const", это всю семантику ломает. Функция должна быть функцией, пока не возникло явной необходимости в ином.

ksa 03.09.2021 08:38

Цитата:

Сообщение от Aetae
бесят меня "объявлтели стрелочек через const"

Так ведь в любой книжке их так и объявляют... :D


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