--- title: Лексична граматика slug: Web/JavaScript/Reference/Lexical_grammar tags: - JavaScript - Посібник - ключове слово - лексична граматика - літерал translation_of: Web/JavaScript/Reference/Lexical_grammar ---
Ця стаття описує лексичну граматику JavaScript. Текст коду скриптів ECMAScript сканується зліва направо та перетворюється на послідовність вхідних елементів, якими є токени, керівні символи, символи розриву рядка, коментарі або пробільні символи. ECMAScript також визначає певні ключові слова та має правила для автоматичної вставки крапки з комою для завершення інструкцій.
Керівні символи не мають візуального відображення, але використовуються для керування інтерпретацією тексту.
Код символа | Назва | Скорочення | Опис |
---|---|---|---|
U+200C |
Роз'єднувач нульової ширини (Zero width non-joiner) |
<ZWNJ> | Розташовується між символами, щоб запобігти об'єднанню їх у лігатури у певних мовах (Вікіпедія). |
U+200D |
Об'єднувач нульової ширини (Zero width joiner) |
<ZWJ> | Розташовується між символами, які інакше не були б об'єднані, щоб відобразити символи у їхній об'єднаній формі у певних мовах (Вікіпедія). |
U+FEFF |
Маркер порядку байтів (Byte order mark) |
<BOM> | Використовується на початку скрипта, щоб позначити його як Юнікод, та для позначення порядку байтів (Вікіпедія). |
Пробільні символи покращують читабельність тексту коду та відділяють токени один від одного. Ці символи зазвичай не є обов'язковими для функціональності коду. Часто використовують інструменти мініфікації для прибирання пробільних символів, щоб зменшити кількість даних, які необхідно передати.
Код символа | Назва | Скорочення | Опис | Екранована послідовність |
---|---|---|---|---|
U+0009 | Табуляція символа (Character tabulation) |
<HT> | Горизонтальна табуляція | \t |
U+000B | Табуляція рядка (Line tabulation) |
<VT> | Вертикальна табуляція | \v |
U+000C | Зміна сторінки (Form feed) |
<FF> | Керівний символ розриву сторінки (Вікіпедія). | \f |
U+0020 | Пробіл (Space) |
<SP> | Звичайний пробіл | |
U+00A0 | Нерозривний пробіл (No-break space) |
<NBSP> | Звичайний пробіл, але відсутня позиція, де можливий розрив рядка | |
Інші | Інші пробільні символи Юнікоду | <USP> | Пробіли Юнікоду на Вікіпедії |
На додачу до пробільних символів, символи розриву рядка використовуються для покращення читабельності тексту коду. Однак, у деяких випадках символи розриву рядка можуть вплинути на виконання коду JavaScript, оскільки існують декілька місць, де вони заборонені. Символи розриву рядка також впливають на процес автоматичної вставки крапки з комою. Символи розриву рядка відповідають класу \s у регулярних виразах.
Лише наступні коди символів Юнікоду сприймаються як символи розриву рядка у ECMAScript, інші символи розриву сприймаються як пробільні (наприклад, символ Наступний рядок (Next Line), NEL, U+0085 вважається пробільним символом).
Код символа | Назва | Скорочення | Опис | Екранована послідовність |
---|---|---|---|---|
U+000A | Зміна рядка (Line Feed) |
<LF> | Символ нового рядка в системах UNIX. | \n |
U+000D | Повернення каретки (Carriage Return) |
<CR> | Символ нового рядка у Commodore та ранній системі Mac. | \r |
U+2028 | Роздільник рядків (Line Separator) |
<LS> | Вікіпедія | |
U+2029 | Роздільник абзаців (Paragraph Separator) |
<PS> | Вікіпедія |
Коментарі використовуються для додавання приміток, зауваг, пропозицій чи застережень до коду JavaScript. Це робить код легшим для читання та розуміння. Їх також можна використовувати для відключення коду, щоб запобігти його виконанню; це може бути цінним інструментом відлагодження.
JavaScript має два давніх способи додавання коментарів у код.
Перший - це коментарі //
; він перетворює весь текст, що розташований за ним, на коментар. Наприклад:
function comment() { // Це однорядковий коментар JavaScript console.log('Всім привіт!'); } comment();
Другий спосіб - це стиль /* */
, він набагато гнучкіший.
Наприклад, ви можете використати його на одному єдиному рядку:
function comment() { /* Це однорядковий коментар JavaScript */ console.log('Всім привіт!'); } comment();
Ви також можете створювати багаторядкові коментарі, ось так:
function comment() { /* Цей коментар містить декілька рядків. Зауважте, що коментар не потрібно завершувати, поки ми не закінчили. */ console.log('Всім привіт!'); } comment();
Ви також можете за бажанням використати його всередині рядка, хоча це може зробити ваш код важчим для читання, тому його варто використовувати з обережністю:
function comment(x) { console.log('Всім ' + x /* вставити значення x */ + ' !'); } comment('привіт');
На додачу, ви можете відключити код, щоб уникнути його виконання, огорнувши код ось так:
function comment() { /* console.log('Всім привіт!'); */ } comment();
У цьому випадку виклик console.log()
не виконується, оскільки знаходиться всередині коментаря. Таким чином можна відключити будь-яку кількість рядків коду.
Спеціалізований третій синтаксис коментарів, коментар шебанг, знаходиться в процесі стандартизації у ECMAScript (дивіться Hashbang Grammar proposal).
Коментар шебанг поводиться так само, як однорядковий коментар (//
). Але він починається з позначки #!
та дозволений лише на самому початку тексту скрипта. Також зауважте, що перед позначкою #!
не можна ставити жодних пробільних знаків. Коментар складається з усіх символів, що стоять після #!
до самого кінця першого рядка; дозволений лише один такий коментар.
Коментар шебанг визначає шлях до специфічного інтерпретатора JavaScript, який ви бажаєте використати для виконання скрипта. Приклад виглядає наступним чином:
#!/usr/bin/env node console.log("Всім привіт");
Заувага: Коментарі шебанг у JavaScript імітують шебанги в Unix, що використовуються для запуску файлів з відповідним інтерпретатором.
Хоча символ BOM перед коментарем шебанг працює у переглядачі, його не радять використовувати у скрипті з шебангом. BOM не працюватиме, якщо ви намагаєтесь виконати скрипт у Unix/Linux. Тому використовуйте UTF-8 без символа BOM, якщо ви хочете виконувати скрипти безпосередньо з оболонки.
Стиль коментарів #!
має використовуватись тільки для того, щоб вказати інтерпретатор JavaScript. У всіх інших випадках просто ставте коментар //
(чи багаторядковий коментар).
Наступні слова зарезервовані як ключові слова специфікацією ECMAScript. Наразі вони не мають спеціальної функціональності, але невдовзі, можливо, матимуть, тому їх не можна використовувати в якості ідентифікаторів.
Наступні слова завжди зарезервовані:
enum
Наступні слова є зарезервованими лише у строгому режимі:
implements
interface
package
private
protected
public
static
Наступні є зарезервованими лише у коді модулів:
await
Далі наведено ключові слова, зарезервовані на майбутнє старшими специфікаціями ECMAScript (ECMAScript від 1 до 3).
abstract
boolean
byte
char
double
final
float
goto
int
long
native
short
synchronized
throws
transient
volatile
Крім того, літерали null
, true
та false
не можна використовувати в якості ідентифікаторів у ECMAScript.
Зарезервовані слова, насправді, стосуються лише ідентифікаторів (на противагу іменам ідентифікаторів). Як описано у es5.github.com/#A.1, це усі імена ідентифікаторів, які не включають зарезервовані слова.
a.import a['import'] a = { import: 'test' }.
З іншого боку, наступний код є некоректним, тому що це ідентифікатор, ними є імена ідентифікаторів без зарезервованих слів. Ідентифікатори використовуються для оголошення функцій, функціональних виразів, оголошення змінних і т.д. Імена ідентифікаторів використовуються для виразу елемента (MemberExpression), виразу виклику (CallExpression) і т.д.
function import() {} // некоректно.
Декілька ідентифікаторів мають спеціальні значення у певному контексті, не будучи ключовими словами жодного виду. Ними є:
Додаткову інформацію дивіться також у {{jsxref("null")}}.
null
Дивіться також додаткову інформацію у {{jsxref("Boolean")}}.
true false
Типи {{jsxref("Число","Number")}} та {{jsxref("BigInt")}} використовують числові літерали.
1234567890 42 // Будьте обережні при використанні нуля попереду 0888 // 888 розбирається як десяткове 0777 // розбирається як вісімкове, 511 у десятковій системі
Зауважте, що десяткові літерали можуть починатися з нуля (0
), за яким іде інша десяткова цифра, але, якщо усі цифри після 0
менші за 8, число інтерпретується як вісімкове. Це не спричинить викидання помилки у JavaScript, дивіться помилку 957513. Також дивіться статтю щодо {{jsxref("parseInt", "parseInt()")}}
Десятковий експоненціальний літерал позначається наступним форматом: beN
; де b
- мантиса (число, ціле чи з рухомою комою), далі символ e
(який слугує роздільником, або експоненціальним показником) та N
, яке вказує порядок – ціле число зі знаком (згідно з 2019 ECMA-262):
0e-5 // => 0 0e+5 // => 0 5e1 // => 50 175e-2 // => 1.75 1e3 // => 1000 1e-3 // => 0.001
Синтаксис двійкових чисел використовує нуль на початку, за яким іде латинська літера "B", маленька чи велика (0b
або 0B
). Оскільки цей синтаксис новий у ECMAScript 2015, дивіться таблицю сумісності з веб-переглядачами, наведену нижче. Якщо цифри після 0b
не є 0 чи 1, викидається наступна помилка {{jsxref("SyntaxError")}}: "Missing binary digits after 0b".
var FLT_SIGNBIT = 0b10000000000000000000000000000000; // 2147483648 var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040 var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607
Синтаксис вісімкових чисел використовує нуль на початку, за яким іде латинська літера "O", маленька чи велика (0o
або 0O)
. Оскільки цей синтаксис новий у ECMAScript 2015, дивіться таблицю сумісності з веб-переглядачами, наведену нижче. Якщо цифри після 0o
виходять за межі діапазону (01234567), викидається наступна помилка {{jsxref("SyntaxError")}}: "Missing octal digits after 0o".
var n = 0O755; // 493 var m = 0o644; // 420 // Також можна просто через нуль на початку // (дивіться заувагу щодо десяткових чисел вище) 0755 0644
Синтаксис шістнадцяткових чисел використовує нуль на початку, за яким іде латинська літера "X", велика чи маленька (0x
або 0X
). Якщо цифри після 0x виходять за межі діапазону (0123456789ABCDEF), викидається наступна помилка {{jsxref("SyntaxError")}}: "Identifier starts immediately after numeric literal".
0xFFFFFFFFFFFFFFFFF // 295147905179352830000 0x123456789ABCDEF // 81985529216486900 0XA // 10
Тип {{jsxref("BigInt")}} є числовим простим типом у JavaScript, який може представляти цілі числа з довільною точністю. Літерали BigInt створюються додаванням n
в кінець цілого числа.
123456789123456789n // 123456789123456789 0o777777777777n // 68719476735 0x123456789ABCDEFn // 81985529216486895 0b11101001010101010101n // 955733
Зауважте, що старі вісімкові числа з просто нулем на початку не працюватимуть з BigInt
:
// 0755n // SyntaxError: invalid BigInt syntax
Для вісімкових чисел BigInt
завжди використовуйте нуль з літерою "o" (великою чи маленькою):
0o755n
Більше інформації щодо BigInt
дивіться у статті Структури даних JavaScript.
Щоб покращити читабельність числових літералів, можна використовувати підкреслення (_
, U+005F
) в якості роздільників:
// роздільники у десяткових числах 1_000_000_000_000 1_050.95 // роздільники у двійкових числах 0b1010_0001_1000_0101 // роздільники у вісімкових числах 0o2_2_5_6 // роздільники у шістнадцяткових числах 0xA0_B0_C0 // роздільники у BigInt 1_000_000_000_000_000_000_000n
Зверніть увагу на ці обмеження:
// Не можна ставити більше одного підкреслення підряд 100__000; // SyntaxError // Не можна ставити в кінці числового літерала 100_; // SyntaxError // Не можна використовувати після нуля на початку 0 0_1; // SyntaxError
Більше інформації дивіться також на сторінках {{jsxref("Object")}} та Ініціалізатор об'єкта.
var o = { a: 'foo', b: 'bar', c: 42 }; // скорочений запис. Нове у ES2015 var a = 'foo', b = 'bar', c = 42; var o = {a, b, c}; // замість var o = { a: a, b: b, c: c };
Більше інформації дивіться також у {{jsxref("Array")}}.
[1954, 1974, 1990, 2014]
Рядковий літерал - це нуль чи більше кодів символів Юнікоду всередині одинарних або подвійних лапок. Коди символів Юнікоду також можуть бути представлені екранованими послідовностями. Усі коди символів можуть з'являтись безпосередньо у рядковому літералі, окрім цих закриваючих кодів символів:
До появи пропозиції зробити весь текст формату JSON дозволеним у ECMA-262, неекрановані U+2028 <LS> та U+2029 <PS> також були заборонені у рядкових літералах.
Будь-які коди символів можуть з'являтись у вигляді екранованої послідовності. Рядкові літерали повертають значення ECMAScript String. Під час генерування цих значень String коди символів Юнікоду кодуються форматом UTF-16.
'foo' "bar"
Шістнадцяткові екрановані послідовності складаються з \x
та рівно двох шістнадцяткових символів, що відображають кодову одиницю чи код символа у діапазоні від 0x0000 до 0x00FF.
'\xA9' // "©"
Екранована послідовність Юнікоду складається рівно з чотирьох шістнадцяткових символів, записаних після \u
. Вона відображає кодову одиницю у кодуванні UTF-16. Для кодів символів від U+0000 до U+FFFF кодова одиниця дорівнює коду символа. Коди символів від U+10000 до U+10FFFF потребують двох екранованих послідовностей, які відображають дві кодові одиниці (сурогатну пару), що використовуються для кодування символа; сурогатна пара відрізняється від коду символа.
Дивіться також {{jsxref("String.fromCharCode()")}} та {{jsxref("String.prototype.charCodeAt()")}}.
'\u00A9' // "©" (U+A9)
Екранування коду символа Юнікоду складається з \u{
, далі код символа у шістнадцятковому форматі, за ним }
. Значення шістнадцяткових символів має знаходитись в діапазоні між 0 та 0x10FFFF включно. Коди символів у діапазоні від U+10000 до U+10FFFF не потребують представлення у вигляді сурогатної пари. Екранування кодів символів було додане у JavaScript у ECMAScript 2015 (ES6).
Дивіться також {{jsxref("String.fromCodePoint()")}} та {{jsxref("String.prototype.codePointAt()")}}.
'\u{2F804}' // CJK COMPATIBILITY IDEOGRAPH-2F804 (U+2F804) // той самий символ у вигляді сурогатної пари '\uD87E\uDC04'
Більше інформації дивіться також у {{jsxref("RegExp")}}.
/ab+c/g // Літерал "порожнього" регулярного виразу // Порожня група необхідна, // щоб уникнути неоднозначності щодо однорядкових коментарів. /(?:)/
Дивіться також шаблонні рядки.
`текстовий рядок` `текстовий рядок 1 текстовий рядок 2` `текст ${вираз} текст` тег `текст ${вираз} текст`
Деякі інструкції JavaScript повинні завершуватись крапкою з комою, і тому підпадають під автоматичну вставку крапки з комою (ASI, automatic semicolon insertion):
let
, const
, інструкція змінноїimport
, export
, оголошення модуляdebugger
continue
, break
, throw
return
Специфікація ECMAScript визначає три правила вставки крапки з комою.
1. Крапка з комою вставляється перед, коли символ розриву рядка чи "}" вважається таким, що недозволений за синтаксисом.
{ 1 2 } 3 // перетворюється на { 1 2 ;} 3;
2. Крапка з комою вставляється в кінці, коли виявлено кінець вхідного набору токенів, але синтаксичний аналізатор неспроможний розібрати єдиний вхідний набір як завершену програму.
Тут ++
не сприймається як постфіксний оператор, що застосовується до змінної b
, тому що між b
та ++
знаходиться символ розриву рядка.
a = b ++c // перетворюється на a = b; ++c;
3. Крапка з комою вставляється в кінці, коли інструкція з обмеженими граматичними застосуваннями супроводжується символом розриву рядка. Ці інструкції з правилом "жодних розривів рядка в цьому місці" наступні:
++
та --
)continue
break
return
yield
, yield*
module
return a + b // перетворюється на return; a + b;
Специфікація |
---|
{{SpecName('ESDraft', '#sec-ecmascript-language-lexical-grammar', 'Lexical Grammar')}} |
{{Compat("javascript.grammar")}}
Наведена нижче таблиця надає щоденний статус реалізації цієї функціональності, оскільки функціональність ще не досягла кросбраузерної стабільності. Дані генеруються запуском відповідних тестів функціональності у Test262, стандартному тестовому наборі JavaScript, на нічній збірці чи на останньому релізі рушія JavaScript кожного веб-переглядача.