Переменные это сплошная «иллюзия»

в 11:16, , рубрики: ECMAScript, javascript, javascript engine, идентификаторы, переменные, Программирование, программист, программисты

Что такое переменная?

Давайте вспомним такое понятие как "переменная", как вы привыкли составлять сложностное определение данному термину? Вот примеры того как вам преподносят на блюдечке расшифровку данного понятия:

  • это хранилище данных, значений;

  • это именованная область в памяти

  • это коробка, имеющая название в которой хранится значение;

  • это значение, которое хранится в ячейки с определенным именем;

  • и другие...

Ну а теперь почему переменных нет :D

Как видите из написанных выше определений, все это звучит очень просто и понятно с точки зрения человеческой логики - но не с точки зрения компьютерной логики (о которой можно философствовать вечно). А теперь просто задайтесь себе вопросом действительно ли это "хранилище данных", или там "коробка со значением" или это все придумали специально некоторые IT гиганты, чтобы упростить всю терминологию и ввести вас как начинающих или уже профессионалов в заблуждение? Многие из вас скажут да-да это реально правда, это точно "хранилище", но лишь незначительная часть скажет "а что за бред вы тут понаписали??".

В языках таких как C, C++, JavaScript понятия переменной НЕ СУЩЕСТВУЕТ от природы!
Если вы окунетесь в англоязычный официальный стандарт каждого языка программирования (ну например те что я перечислил выше), то там понятия переменной не упоминается. Вы меня сразу спросите да как же так? а что же тогда происходит в момент var x = 5; или там int x =5;??

Давайте объясню на примере JavaScript согласно официальной спецификации ECMAScript у вас создается некоторый идентификатор x, но не совсем конечно так, точнее будет если опираться прямо на спецификацию это IdentifierReference (сокращенно IdRef, ref - означает ссылка) - x это как бы ссылка на идентификатор. Щас прямо зачитаю вам строчку из спецификации:

"IdentifierReference: там Identifier" — то Ascending это просто имя, которое вы задаёте. Но а что же это вот имя, на что оно ссылается?

Когда вы написали var x = 5;

Вы создали x который как раз и является этим самым IdentifierReference и ссылается (указывает) на некую привязку BindingIdentifier, которая в свою очередь является прямой связью между этим x и некоторым значением 5. Что делает движок? А движок вызывает внутреннюю абстрактную операцию ResolveBinding("x") дабы понять что за этим x - скрывается. Получается что x - в данном случае не хранит значение 5, а ссылается на него через привязку.

Как работает ResolveBinding?

ResolveBinding — абстрактная операция, описанная в официальной спецификации ECMAScript. Согласно спецификации, операция принимает некоторое имя (например в нашем случае, "x") и, опционально, среду (environment или если сокращенно то env), а возвращает либо ссылку на значение, либо ошибку. Если env не указан, то так называемый current env берётся из current context выполнения — это LexicalEnvironment (LexEnv). Фактически LexEnv - с точки зрения человеческой логики (не компьютерной щас) некоторая таблица, где уже записаны все имена и их значения в current scope.

из спецификации

из спецификации

Давайте посмотрим на картинку;

  • итак, если env не передан или является undefined тогда идет

    • в env устанавливается current scope.

  • далее подтверждение, что env реально scope а не абы что:D

  • дальше там проверка на strict mode.

  • и уже после идет вызов GetIdentifierReference с env, name, strict.

в целом мы можем пойти и дальше и понять, как работает GetIdentifierReference :D

из спецификации

из спецификации

Выше удалось выяснить, что GetIdentifierReference принимает ровно три аргумента: это среду (env), некоторое имя (name, например для нас это, "x") и флаг strict mode.

  • итак если env is null тогда

    • возврат записи (x типа не удалось определить)

    • тут также стоит отметить что в strict mode это вероятно вызовет ошибку RefError, а в not strict mode создаст глобальный идентификатор.

  • далее этот вот has binding это вопрос к env - "у тебя есть привязка к name?"

  • в случае если есть: возврат записи Ref.. Record

  • в случае если нет: заглядываем в outer env (внешняя среда). И там рекурсией вызывается GetIdentifierReference - то есть проходит по цепочке scop-ов вверх пока не найдет нужный идентификатор или дойдет до null.

Зайдем на MDN:D и проверим себя:D

ссылка mdn: https://developer.mozilla.org/ru/docs/Learn_web_development/Core/Scripting/Variables

о переменных в mdn

о переменных в mdn

Разберём то, что они тут понаписали: во‑первых, как вы уже поняли, переменная — это не контейнер, это скорее абстракция или, как я называю, «иллюзия программиста». MDN говорит, что name — это переменная, которая сохраняет имя от prompt, ну а потом там у них в примере alert(). Начнём с того, что prompt, alert — это в действительности не относится напрямую к языку JavaScript, но об этом я расскажу в другой статье. Правильно сказать будет, что name — это идентификатор, который ссылается на некоторое значение «имя», полученное от prompt. И никакого «сохранения в переменной» и быть не может. Забудьте, просто забудьте об этом!!! Это простой пример как раз того, что крупный гигант MDN просто пытается донести всё простым языком, упростив то, что упрощать никак нельзя. Это кардинально неверное объяснение и применение того, что написано в официальной спецификации языка JavaScript в ECMAScript.

Автор: andrei777777

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js