Использование зарезервированных слов в Javascript

#javascript #identifier #ecma262

#javascript #идентификатор #ecma262

Вопрос:

В Javascript существуют различные зарезервированные слова, которые нельзя использовать внутри Identifiers ; некоторые из них на самом деле зарезервированы для будущего использования. Чтобы немного прояснить, Identifier это Identifier Name , но не зарезервированное слово. Точная грамматика имен идентификаторов здесь не имеет значения.

Однако, согласно последнему абзацу здесь, кажется, что есть какое-то место, где допустимо использовать любое Identifier Name , даже если это зарезервированное слово. В статье упоминается как допустимый

 a.import
a["import"]
a = { import: "test" }
  

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

Фактически, этот ресурс обозначает

 foo.if
  

как недопустимый код.

Есть ли какие-то места, где зарезервированные слова действительно действительны?

В качестве мотивации я пишу API, в котором имело бы смысл передавать объекты вида

 {
    in: foo,
    out: bar
}
  

но я не хочу заставлять пользователей заключать в квадратные скобки in .

Комментарии:

1. Если «in» и «out» имеют наибольший смысл семантически для вашего API, тогда продолжайте и используйте их, даже если пользователям приходится их цитировать. (Я полагаю, вы имели в виду «заключить в кавычки», а не «заключить в скобки».)

Ответ №1:

Это изменение в ECMA-262 между выпусками 3 и 5 (которое вы можете получить здесь).

В обоих изданиях раздел 7.6 определяет идентификатор как

 Identifier ::
    IdentifierName but not ReservedWord
  

Однако в разделе 11.2.1 средства доступа к свойствам, использующие точечную нотацию, были изменены с

 MemberExpression . Identifier
CallExpression . Identifier
  

в редакции 3 для

 MemberExpression . IdentifierName
CallExpression . IdentifierName
  

в версии 5, ie, использование зарезервированных имен в качестве средств доступа к точкам действительно теперь разрешено.

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

PS: Немного покопавшись, я нашел следующее в письме от Аллена Вирфса-Брока, редактора проекта для версии 5:

Грамматика ES3 не позволяет использовать зарезервированные слова (такие как true и false) в качестве имени свойства или справа от точки в выражении MemberExpression. Ваши тесты подтверждают, что большинство реализаций соответствуют этому ограничению, в то время как FF имеет «нестандартное» расширение, которое позволяет использовать зарезервированные слова (или, по крайней мере, те, которые вы тестировали) в этих контекстах.

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

Обратите внимание, что ECMAScript 3.1 был первоначальным названием для того, что теперь известно как ECMAScript 5.

Ответ №2:

Хотя большинство браузеров не выдают ошибку на a.import , это не строго законно. Если вы хотите использовать зарезервированное слово, вы должны заключить его в кавычки.

Посетите http://wwwjslint.com и вставьте следующий код:

 var d = {
    'in': 1
};
  

Этот код допустим. Однако при удалении кавычек генерируется ошибка:

Проблема в символе 5 строки 2: ожидал идентификатор, а вместо этого увидел ‘in’ (зарезервированное слово).

Комментарии:

1. На самом деле это не отвечает на мой вопрос. Да, jslint жалуется, но я не уверен, что Крокфорд понял это правильно. Конечно, я знаю, что каждая строка может быть использована в качестве имени свойства в кавычках. Но мне было интересно, почему ребята из MDN утверждают, что кавычки можно опустить. Я больше искал какую-то ссылку на соответствующую часть спецификации, которую я не мог найти сам.

2. @Andrea Вызовите консоль JavaScript и введите var d = {a:1} . Результатом является {a:1} . При вводе {import:1} отображается следующая ошибка: SyntaxError: import is a reserved identifier . (Firefox 7.0.1). Для «реального» примера возникновения этой проблемы взгляните на: userscripts.org/topics/77990 . Разработчик не знал о зарезервированных словах и столкнулся с проблемой.

3. @RobW — var d = {import:1}; не выдает ошибку для меня.

4. @JamesAllardice Без var d префикса.

5. Хм … если это не работает в Firefox, это плохая идея, даже если это было законно! 🙂

Ответ №3:

В статье MDN приводится спецификация Ecmascript 5, которой соответствует Firefox, но не все браузеры соответствуют ей таким образом, т. е. не все браузеры совместимы с Ecmascript 5.

Ответ №4:

Вы не можете полагаться на их работоспособность во всех браузерах / реализациях, если они не указаны в кавычках.

Я бы попытался изменить их на что-то вроде «ввод» и «вывод», если это имеет смысл. Дополнительное предложение, которое вам придется добавить в документацию о том, что «in» нуждается в кавычках, вероятно, не стоит того, чтобы иметь «идеальные» имена идентификаторов.