Почему разрешено использовать let в качестве имени переменной? - PullRequest
3 голосов
/ 01 августа 2020

Мне было интересно, может ли кто-нибудь обратить внимание на какое-то странное поведение, которое я только что обнаружил. Итак, я работал в узле REPL, выполняя код перед тем, как вставить его в модуль, и я допустил опечатку (ну, не полностью заполнил строку) let = 5. Я ожидал, что это приведет к ошибке, но REPL принял это, и я могу видеть значение с результатами выражения и console.logs. Так я начал возиться. Я знаю, что в REPL переменные без let / const / var считаются глобальными, но мне было интересно, почему REPL позволяет нам назначать let таким образом? Ниже я перечислил то, что я пробовал (только в REPL, не пробовал в модульном скрипте).

let = 5; //works
var = 5; //SyntaxError: Unexpected token "="
const = 5; //SyntaxError: Unexpected token "="

let let = 5; //SyntaxError: let is disallowed as a lexically bound name
var let = 5; //works
const let = 5; //SyntaxError: let is disallowed as a lexically bound name

let var = 5; //SyntaxError: Unexpected token "var"
var var = 5; //SyntaxError: Unexpected token "var"
const var = 5; //SyntaxError: Unexpected token "var"

let const = 5; //SyntaxError: Unexpected token "const"
var const = 5; //SyntaxError: Unexpected token "const" 
const const = 5; //SyntaxError: Unexpected token "const"  

Итак, почему let = 5 и var let = 5 работают, когда логически (для меня, по крайней мере, ), все эти операторы должны были быть синтаксическими ошибками?

Edit Чтобы добавить, let по-прежнему работает так же, когда используется для назначения переменной после назначения. Например,

let = 5; 
let test = {}; 
console.log(let,test)

работает и отображает 5 {}

Ответы [ 2 ]

4 голосов
/ 01 августа 2020

const и let были представлены как Будущие зарезервированные слова в ECMA2011 .

ECMA2011 - Введение const и let как Будущие зарезервированные слова

7.6.1.2 Будущие зарезервированные слова

Следующие слова используются в качестве ключевых слов в предлагаемых расширениях и поэтому зарезервированы, чтобы учесть возможность принятие этих расширений в будущем.

FutureReservedWord ::

  • class
  • enum
  • расширяет
  • super
  • const
  • экспорт
  • import

Следующие токены также считаются FutureReservedWords , если они встречаются в коде строгого режима (см. 10.1. 1). Вхождение любого из этих токенов в код строгого режима в любом контексте, где возникновение FutureReservedWord приведет к ошибке, также должно привести к эквивалентной ошибке:

  • реализует
  • let
  • частный
  • publi c
  • выход
  • интерфейс
  • пакет
  • защищенный
  • stati c

ECMA2012 - Утвержденные ключевые слова

Позже в ECMA2012 оба слова были добавлены как ключевые слова, которые не могут использоваться как идентификаторы .

7.6.1.1 Ключевые слова

Следующие токены являются ключевыми словами ECMAScript и не могут использоваться как идентификаторы в программах на ECMAScript.

ключевое слово ::

  • break
  • удалить
  • импорт
  • это
  • корпус
  • do
  • дюйм
  • бросок
  • catch
  • else
  • instanceof
  • попробовать
  • класс
  • экспорт
  • пусть
  • тип
  • продолжить
  • наконец
  • новый
  • var
  • const
  • для
  • возврат
  • void
  • отладчик
  • функция
  • супер
  • при
  • по умолчанию
  • если
  • переключатель
  • с

Тогда как const используется как идентификатор - выдает ошибки в каждом режиме, let выдает только ошибку, le находится в строгом режиме, что по-прежнему имеет место в вашем примере:

Действительный

Использование let в качестве идентификатора без строгого режима.

(function(){
    //REM: Works
    var let = 5;
    console.log(let);
  })();

Недействительный

Использование const в качестве идентификатора без строгого режима.

(function(){
    //REM: Throws an error
    var const = 5;
    console.log(const);
})();

Использование let или const в качестве идентификаторов в строгом режиме.

(function(){
    'use strict';
    //REM: Throws an error
    var let = 5;
    console.log(let);
})();

(function(){
    'use strict';
    //REM: Throws an error
    var const = 5;
    console.log(const);
})();

Таким образом, исторически ECMA был более строгим с ключевым словом const, чем let из get go. Хотя let не может использоваться как Идентификатор с ECMA2012, я предполагаю, что он был упущен из виду из-за обратной совместимости.

Здесь - последняя спецификация let и const.

4 голосов
/ 01 августа 2020

const и let являются недавними добавлениями к JS, но в течение длинного времени до того, как они были добавлены, const было зарезервированным ключевым словом (предположительно на том основании, что оно считалось будет вероятным будущим дополнением к языку).

Поскольку let раньше было допустимым именем переменной, это предположительно для обратной совместимости.

...