Комментарии 4
А ещё есть function expression & function declaration. Первое не "всплывает" при hoisting'e, второе всплывает.
Во втором примере есть крохотная неточность: return function sayHello - это не декларация, а функциональное выражение, и потому переменная sayHello находится в лексическом окружении sayHello, а не sayHelloDearFriend
Проблема этого материала ровно та же, что у его предыдущей части - автор выливает на читателя кашу из своих измышлизмов о языке приправленную отрывками спецификации. Иными словами - ровно ничего из того что говорит автор руководства, в реальности официальной спецификации - не существует. При этом, автору нужно отдать должное, его материал, хотя бы делает попытку описать язык таким какой он есть. Пусть у него ничего не получилось и все это превратилось в очередной пересказ мифов о языке, но этот пересказ оказался намного ближе к реальности чем многие другие. Далее по фактам.
Никто не знает, как рассказать про лексическое окружение (ЛО), даже если слышал такой термин. Тут и пошутить не о чем.
Я знаю.
Более того, я сообщу автору неожиданную для него новость - в рамках языка JavaScript термина лексическое окружение - не существует. Это выдумка автора и прочих, кто пытается рассуждать о языке JavaScript с точки зрения привычных для них норм, справедливых, возможно, для других языков где они официально закреплены, но не для JavaScript.
Чтобы убедиться в этом, достаточно открыть официальную спецификацию языка и сделать сквозной поиск по ключевому слову Lexical Environment. Найти там 4 совпадения, 3 из которых описывают особый случай функционирования with statement и 1 в плоскости описания абстракции функционального обьекта. После чего задаться справедливым вопросом - а может я чего-то не понимаю в том, как это язык организован?
Может тот факт, что официальная спецификация, описывает нормы работы языка при помощи иных - отличных от привычных мне терминов, говорит о том, что то, что я о языке знаю не отвечает реальности? Может все то, что я знаю о языке это чья-то аналогия? Может быть, если я пишу материал, с прицелом пояснить что-то про язык, я должен это сделать опираясь прежде всего на официальную спецификацию? А не пересказывать в сотый раз кем-то ранее придуманные аналогии, которые не имеют ничего общего с реальність в плоскости официальных норм языка JavaScript?
Я подчеркиваю - есть официальная спецификация языка, которая описывает все процессы в нем. И есть аналогии на этот счет, которые просто пытаются пояснить что-то в языке более "понятным" образом, но при этом они не перестают быть АНАЛОГИЯМИ, ВЫМЫСЛОМ, мыслительным экспериментом - НО НЕ частями языка.
Весь выше обозначенный материал, является примером того, как автор подменяет своими аналогиями, то чем на самом деле язык является. И пример с Lexical Environment очень показателен. Поскольку автор, используя распространенный среди программистов жаргон о "областях видимости" "лексических окружениях" "замыканиях" "funarg проблемы", говорит ТОЛЬКО об этом ЖАРГОНЕ, выдавая это за то, чем якобы язык является.
Автор ошибается. Язык JavaScript, с точки зрения официальной спецификации другой. В нем нет замыканий, областей видимости и лексических окружений в форме, в которой говорит автор статьи.
А что же там есть?
Добро пожаловать в спецификацию языка, в которой предложена очень простая и логичная концепция окружений - Environment. Которая содержит так же подобие термина Lexical Environment, но не врамках Environment языка, а в рамках non-normative пояснения того как осуществляется разрешение this в рамках arrow function. И только в этом.
Официальная спецификация ES6 определяет этот(Лексическое окружение) термин так:
Нет никакого Lexical Environment в рамках официальной спецификации. Откуда автор взял это определение нужно спросить лично у него.
Автор дай ссылку на официальную спецификацию - где бы было это определение!
Автор не сможет этого сделать. По одной простой причине, что даже если бы в рамках спецификации языка JavaScript были закреплены термины типа Лексическое окружение, Замыкания, области видимости - то они не имели бы смысла потому, что эти термины имеют значение только в плоскости рассуждения о том, как бы все это работало в случае когда видимость идентификаторов определялась не лексическим окружением а динамическим. Эти термины имеют значение, только в плоскости рассуждений о преимуществах той или иной формы реализации в языках программирования.
Технически ЛО представляет собой объект с двумя свойствами:
Дальше автор стал наделять абстракцию, которая не имеет отношении к языку, деталями, которые действительно существуют.
В языке JavaScript, согласно официальной спецификации, принята за основу очень простая и логичная концепция окружений. Эта концепция, является не только артефактом спецификации ECMA, это концепция признана и другими спецификациями, например официальной спецификацией HTML5.
Суть этой концепции заключается в том, что выполнение любого кода, сопровождается некоторым окружением Environment - служебной областью, которая содержит все необходимое для выполнения этого кода. В том числе и имена идентификаторов. Которые в рамках этой спецификации поделены на структуры: function environment, declarative environment, object environment, global environment и module environment.
Части поведения которых, можно было бы охарактеризовать как что-то, что схоже с привычным жаргоном Lexical Environment. Подчеркиваю - детали. Environment языка JavaScript это не тоже самое, что часть слова Lexical Environment. Это вообще про разное, но схожее.
Это служебный объект, и получить к нему доступ напрямую мы никак не можем.
Правда в том, что все Environment в официальной спецификации - это действительно артефакты спецификации, задачи которых описать прниципы функционирования языка. Как правда и то, что автор матерала несет чушь, будто бы в этой спецификации есть используемое им Lexical Environment. Это не так. Ничего подобного, с точки зрения официальной спецификации в JS нет.
HOISTING
Никакого HOISITNG в JS нет. Все спекуляции на тему хостинга в JS связаны с неправильным переводом и, как следствие, пониманием термина HoistableDeclaration который описывает частный случай работы с декларациями в JS. Существование которого касается только случая, когда декларация функционального обьекта должна приводит к тому, что его использование становится возможным с начала выполнения кода.
И так далее и тому подобное.
Как первая часть руководства, так и вторая имеет один основной изьян - она не имеет ничего общего с официальной спецификацией языка и занимается пересказом распространенных аналогий или мифов о нем. Хотя и делает попытку, отчасти, приблизиться к тому, как в действительности работает язык JavaScript.
JavaScript: The World's Most Misunderstood Programming Language. Douglas Crockford 2001 год.
На дворе 2023 год и вместо того, чтобы разобраться в языке, авторы публикуют свои имзышлизмы на его счет.
Полезная статья для новичков)
JavaScript для самых маленьких. Часть 2