Gramática léxica

Esta página describe la gramática léxica de JavaScript. El texto de origen de las secuencias de órdenes ECMAScript se analiza de izquierda a derecha y se convierte en una secuencia de elementos de entrada tales como fichas, caracteres de control, finalizadores de renglón, comentarios y espacios en blanco. ECMAScript define asimismo determinadas palabras claves y literales y cuenta con reglas de inserción automática de punto y coma para finalizar declaraciones.

Caracteres de control

Los caracteres de control no tienen ninguna representación visula pero se utilizan para controlar la interpretación del texto

Caracteres de control de formato en Unicode
Punto de código Nombre Abreviatura Descripción
U+200C Zero width non-joiner <ZWNJ> Placed between characters to prevent being connected into ligatures in certain languages (Wikipedia).
U+200D Zero width joiner <ZWJ> Placed between characters that would not normally be connected in order to cause the characters to be rendered using their connected form in certain languages (Wikipedia).
U+FEFF Byte order mark <BOM> Used at the start of the script to mark it as Unicode and the text's byte order (Wikipedia).

Espacio en blanco

Los caracteres de espacio en blanco mejoran la legibilidad del texto fuente y separan las fichas las unas de las otras. Estos caracteres no suelen ser necesarios para la funcionalidad del código. A menudo se utilizan herramientas miniaturizadoras para quitar el espacio en blanco y así reducir la cantidad de datos que debe transmitirse.

Caracteres de espacio en blanco
Punto de código Nombre Abreviatura Descripción Secuencia de escape
U+0009 Character tabulation <HT> Horizontal tabulation \t
U+000B Line tabulation <VT> Vertical tabulation \v
U+000C Form feed <FF> Page breaking control character (Wikipedia). \f
U+0020 Space <SP> Normal space
U+00A0 No-break space <NBSP> Normal space, but no point at which a line may break
Others Other Unicode space characters <USP> Spaces in Unicode on Wikipedia

Finalizadores de renglón

Como los caracteres de espacio en blanco, los caracteres finalizadores de renglón permiten mejorar la legibilidad del texto fuente. Sin embargo, en algunos casos, los finalizadores de renglón pueden influir en la ejecución del código JavaScript, dado que hay algunos sitios donde están prohibidos. Los finalizadores de renglón también afectan el proceso de inserción automática de punto y coma. Los finalizadores de renglón pueden encontrarse mediante la clase \s en las expresiones regulares.

Únicamente los puntos de código de Unicode enumerados a continuación se reconocen como finalizadores de renglón en ECMAScript; otros caracteres de salto de renglón se tratan como si fuesen espacio en blanco (por ejemplo, Próximo renglón, NEL, U+0085 se considera espacio en blanco).

Caracteres finalizadores de renglón
Punto de código Nombre Abreviatura Descripción Secuencia de escape
U+000A Line Feed <LF> New line character in UNIX systems. \n
U+000D Carriage Return <CR> New line character in Commodore and early Mac systems. \r
U+2028 Line Separator <LS> Wikipedia
U+2029 Paragraph Separator <PS> Wikipedia

Comentarios

Los comentarios permiten añadir pistas, notas, sugerencias o alertas al código en JavaScript, lo que puede facilitar su lectura y comprensión. También permiten desactivar código para evitar su ejecución; visto así, puede constituir una valiosa herramienta de depuración.

JavaScript por mucho tiempo ha contado con dos maneras de añadir comentarios al código.

La primera es el comentario //; todo el texto que se sitúe tras estos dos caracteres en el mismo renglón serán un comentario. Por ejemplo:

function comment() {
  // Este es un comentario en JavaScript de un renglón
  console.log('Hello world!');
}
comment();

El segundo método es el estilo /* */, mucho más flexible.

Por ejemplo, se puede emplear en un solo renglón:

function comment() {
  /* Este es un comentario en JavaScript de un renglón */
  console.log('Hello world!');
}
comment();

También puede ampliar un comentario por varios renglones:

function comment() {
  /* Este comentario abarca varios renglones. Observe que no
     hace falta finalizar el comentario si no hemos terminado. */
  console.log('Hello world!');
}
comment();

Además puede emplearse en medio de un renglón, si lo prefiere, aunque esto podría dificultar la lectura del código; utilícelo con precaución:

function comment(x) {
  console.log('Hello ' + x /* insertar valor de x */ + ' !');
}
comment('world');

Asimismo, meter código en un comentario desactivará su ejecución:

function comment() {
  /* console.log('Hello world!'); */
}
comment();

En este caso, no se emite nunca la llamada console.log(), dado que está encerrada en un comentario. De este modo es posible desactivar cualquier cantidad de renglones de código.

Comentarios hashbang

Una tercera sintaxis, el comentario hashbang, está en vías de ser estandarizada en ECMAScript para propósitos especializados (consulte la propuesta Gramática hashbang).

Un comentario hashbang se comporta de la misma manera que uno de renglón único (//), pero comienza con #! y únicamente es válido en el comienzo absoluto de una secuencia de órdenes o un módulo. Tampoco se permite añadir espacios en blanco de ningún tipo antes de #!. El comentario consta de todos los caracteres tras #! hasta el término del renglón; solo se permite uno de estos comentarios.

El comentario hashbang especifica la ruta hacia un intérprete de JavaScript concreto que quiere utilizar para ejecutar la secuencia de órdenes. He aquí un ejemplo:

#!/usr/bin/env node

console.log("Hello world");

Nota: los comentarios hashbang en JavaScript imitan a los shebangs de Unix, utilizados para ejecutar archivos con el intérprete correcto.

Aunque el BOM situado antes del comentario hashbang funcionará en un navegador, no se aconseja utilizar BOM en una secuencia de órdenes con hasbang. El BOM no funcionará cuando intente ejecutar la secuencia de órdenes en Unix/Linux. Utilice UTF-8 sin BOM si quiere ejecutar secuencias de órdenes directamente desde la consola.

You must only use the #! comment style to specify a JavaScript interpreter. In all other cases just use a // comment (or mulitiline comment).

Palabras clave

Palabras clave desde ECMAScript 2015

Futuras palabras clave reservadas

The following are reserved as future keywords by the ECMAScript specification. They have no special functionality at present, but they might at some future time, so they cannot be used as identifiers.

These are always reserved:

  • enum

The following are only reserved when they are found in strict mode code:

  • implements
  • interface
  • let
  • package
  • private
  • protected
  • public
  • static

The following are only reserved when they are found in module code:

  • await

Futuras palabras clave reservadas en normas anteriores

The following are reserved as future keywords by older ECMAScript specifications (ECMAScript 1 till 3).

  • abstract
  • boolean
  • byte
  • char
  • double
  • final
  • float
  • goto
  • int
  • long
  • native
  • short
  • synchronized
  • throws
  • transient
  • volatile

Additionally, the literals null, true, and false cannot be used as identifiers in ECMAScript.

Uso de palabras reservado

Reserved words actually only apply to Identifiers (vs. IdentifierNames) . As described in es5.github.com/#A.1, these are all IdentifierNames which do not exclude ReservedWords.

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

On the other hand the following is illegal because it's an Identifier, which is an IdentifierName without the reserved words. Identifiers are used for FunctionDeclaration, FunctionExpression, VariableDeclaration and so on. IdentifierNames are used for MemberExpression, CallExpression and so on.

function import() {} // Illegal.

Literales

Literal nulo

See also null for more information.

null

Literal booleano

See also Boolean for more information.

true
false

Literales numéricos

The Number and BigInt types use numeric literals.

Decimal

1234567890
42

// Caution when using with a leading zero:
0888 // 888 parsed as decimal
0777 // parsed as octal, 511 in decimal

Note that decimal literals can start with a zero (0) followed by another decimal digit, but If all digits after the leading 0 are smaller than 8, the number is interpreted as an octal number. This won't throw in JavaScript, see error 957513. See also the page about parseInt()

Binario

Binary number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "B" (0b or 0B). Because this syntax is new in ECMAScript 2015, see the browser compatibility table, below. If the digits after the 0b are not 0 or 1, the following SyntaxError is thrown: "Missing binary digits after 0b".

var FLT_SIGNBIT  = 0b10000000000000000000000000000000; // 2147483648
var FLT_EXPONENT = 0b01111111100000000000000000000000; // 2139095040
var FLT_MANTISSA = 0B00000000011111111111111111111111; // 8388607

Octal

Octal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "O" (0o or 0O). Because this syntax is new in ECMAScript 2015, see the browser compatibility table, below. If the digits after the 0o are outside the range (01234567), the following SyntaxError is thrown: "Missing octal digits after 0o".

var n = 0O755; // 493
var m = 0o644; // 420

// Also possible with just a leading zero (see note about decimals above)
0755
0644

Hexadecimal

Hexadecimal number syntax uses a leading zero followed by a lowercase or uppercase Latin letter "X" (0x or 0X). If the digits after 0x are outside the range (0123456789ABCDEF), the following SyntaxError is thrown: "Identifier starts immediately after numeric literal".

0xFFFFFFFFFFFFFFFFF // 295147905179352830000
0x123456789ABCDEF   // 81985529216486900
0XA                 // 10

Literal BigInt

The BigInt type is a numeric primitive in JavaScript that can represent integers with arbitrary precision. BigInt literals are created by appending n to the end of an integer.

123456789123456789n     (decimal, base 10)
0o777777777777n         (octal, base 8)
0x123456789ABCDEFn      (hexadecimal, "hex" or base 16)
0b11101001010101010101n (binary, base 2)

Note that legacy octal numbers with just a leading zero won't work for BigInt:

// 0755n
// SyntaxError: invalid BigInt syntax

For octal BigInt numbers, always use zero followed by the letter "o" (uppercase or lowercase):

0o755n

For more information about BigInt, see also JavaScript data structures.

Separadores numéricos

To improve readability for numeric literals, underscores (_, U+005F) can be used as separators:

// separators in decimal numbers
1_000_000_000_000
1_050.95

// separators in binary numbers
0b1010_0001_1000_0101

// separators in octal numbers
0o2_2_5_6

// separators in hex numbers
0xA0_B0_C0

// separators in BigInts
1_000_000_000_000_000_000_000n

Cabe tener en cuenta estas limitaciones:

// More than one underscore in a row is not allowed
100__000; // SyntaxError

// Not allowed at the end of numeric literals
100_; // SyntaxError

// Can not be used after leading 0
0_1; // SyntaxError

Literales para objetos

See also Object and Object initializer for more information.

var o = { a: 'foo', b: 'bar', c: 42 };

// shorthand notation. New in ES2015
var a = 'foo', b = 'bar', c = 42;
var o = {a, b, c};

// instead of
var o = { a: a, b: b, c: c };

Literales para matrices

See also Array for more information.

[1954, 1974, 1990, 2014]

Literales para cadenas

A string literal is zero or more Unicode code points enclosed in single or double quotes. Unicode code points may also be represented by an escape sequence. All code points may appear literally in a string literal except for these closing quote code points:

  • U+005C \(backslash),
  • U+000D <CR>,
  • and U+000A <LF>.

Prior to the proposal to make all JSON text valid ECMA-262, U+2028 <LS> and U+2029 <PS>, were also disallowed from appearing unescaped in string literals.

Any code points may appear in the form of an escape sequence. String literals evaluate to ECMAScript String values. When generating these String values Unicode code points are UTF-16 encoded.

'foo'
"bar"

Secuencias de escape hexadecimales

Hexadecimal escape sequences consist of \x followed by exactly two hexadecimal digits representing a code unit or code point in the range 0x0000 to 0x00FF.

'\xA9' // "©"

Secuencias de escape Unicode

A Unicode escape sequence consists of exactly four hexadecimal digits following \u. It represents a code unit in the UTF-16 encoding. For code points U+0000 to U+FFFF, the code unit is equal to the code point. Code points U+10000 to U+10FFFF require two escape sequences representing the two code units (a surrogate pair) used to encode the character; the surrogate pair is distinct from the code point.

See also String.fromCharCode() and String.prototype.charCodeAt().

'\u00A9' // "©" (U+A9)

Escapes de puntos de código de Unicode

A Unicode code point escape consists of \u{, followed by a code point in hexadecimal base, followed by }. The value of the hexadecimal digits must be in the range 0 and 0x10FFFF inclusive. Code points in the range U+10000 to U+10FFFF do not need to be represented as a surrogate pair. Code point escapes were added to JavaScript in ECMAScript 2015 (ES6).

See also String.fromCodePoint() and String.prototype.codePointAt().

'\u{2F804}' // CJK COMPATIBILITY IDEOGRAPH-2F804 (U+2F804)

// the same character represented as a surrogate pair
'\uD87E\uDC04'

Literales para expresiones regulares

See also RegExp for more information.

/ab+c/g

// An "empty" regular expression literal
// The empty non-capturing group is necessary 
// to avoid ambiguity with single-line comments.
/(?:)/

Literales para plantillas

See also template strings for more information.

`string text`

`string text line 1
 string text line 2`

`string text ${expression} string text`

tag `string text ${expression} string text`

Inserción automática de punto y coma

Some JavaScript statements must be terminated with semicolons and are therefore affected by automatic semicolon insertion (ASI):

  • Empty statement
  • let, const, variable statement
  • import, export, module declaration
  • Expression statement
  • debugger
  • continue, break, throw
  • return

The ECMAScript specification mentions three rules of semicolon insertion.

1. A semicolon is inserted before, when a Line terminator or "}" is encountered that is not allowed by the grammar.

{ 1 2 } 3 

// is transformed by ASI into 

{ 1 2 ;} 3;

2. A semicolon is inserted at the end, when the end of the input stream of tokens is detected and the parser is unable to parse the single input stream as a complete program.

Here ++ is not treated as a postfix operator applying to variable b, because a line terminator occurs between b and ++.

a = b
++c

// is transformend by ASI into

a = b;
++c;

3. A semicolon is inserted at the end, when a statement with restricted productions in the grammar is followed by a line terminator. These statements with "no LineTerminator here" rules are:

  • PostfixExpressions (++ and --)
  • continue
  • break
  • return
  • yield, yield*
  • module
return
a + b

// is transformed by ASI into

return;
a + b;

Especificaciones

Especificación Estado Comentario
ECMAScript 1st Edition (ECMA-262) Standard Initial definition.
ECMAScript 5.1 (ECMA-262)
La definición de 'Lexical Conventions' en esta especificación.
Standard
ECMAScript 2015 (6th Edition, ECMA-262)
La definición de 'Lexical Grammar' en esta especificación.
Standard Added: Binary and Octal Numeric literals, Unicode code point escapes, Templates
ECMAScript Latest Draft (ECMA-262)
La definición de 'Lexical Grammar' en esta especificación.
Draft

Compatibilidad en navegadores

Update compatibility data on GitHub
DesktopMobileServer
ChromeEdgeFirefoxInternet ExplorerOperaSafariAndroid webviewChrome para AndroidFirefox para AndroidOpera para AndroidSafari en iOSSamsung InternetNode.js
Array literals ([1, 2, 3])Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 4Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Binary numeric literals (0b)Chrome Soporte completo 41Edge Soporte completo 12Firefox Soporte completo 25IE Sin soporte NoOpera Soporte completo 28Safari Soporte completo 9WebView Android Soporte completo 41Chrome Android Soporte completo 41Firefox Android Soporte completo 25Opera Android Soporte completo 28Safari iOS Soporte completo SiSamsung Internet Android Soporte completo 4.0nodejs Soporte completo 4.0.0
Soporte completo 4.0.0
Soporte completo 0.12
Deshabilitado
Deshabilitado From version 0.12: this feature is behind the --harmony runtime flag.
Boolean literals (true/false)Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 3Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Decimal numeric literals (1234567890)Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 3Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Hashbang (#!) comment syntax
Experimental
Chrome Soporte completo 74Edge Sin soporte NoFirefox Soporte completo 67IE Sin soporte NoOpera ? Safari ? WebView Android Soporte completo 74Chrome Android Soporte completo 74Firefox Android Soporte completo 67Opera Android ? Safari iOS ? Samsung Internet Android Sin soporte Nonodejs Soporte completo Si
Hexadecimal escape sequences ('\0xA9')Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 4Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Hexadecimal numeric literals (0xAF)Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 3Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Null literal (null)Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 3Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Numeric separators (1_000_000_000_000)Chrome Soporte completo 75Edge Sin soporte NoFirefox Soporte completo 70IE Sin soporte NoOpera Soporte completo 62Safari ? WebView Android Soporte completo 75Chrome Android Soporte completo 75Firefox Android Sin soporte NoOpera Android Sin soporte NoSafari iOS ? Samsung Internet Android Sin soporte Nonodejs Soporte completo Si
Octal numeric literals (0o)Chrome Soporte completo 41Edge Soporte completo 12Firefox Soporte completo 25IE Sin soporte NoOpera Soporte completo 28Safari Soporte completo 9WebView Android Soporte completo 41Chrome Android Soporte completo 41Firefox Android Soporte completo 25Opera Android Soporte completo 28Safari iOS Soporte completo SiSamsung Internet Android Soporte completo 4.0nodejs Soporte completo Si
Regular expression literals (/ab+c/g)Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 4Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
String literals ('Hello world')Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 3Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Unicode escape sequences ('\u00A9')Chrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 4Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si
Unicode point escapes (\u{})Chrome Soporte completo 44Edge Soporte completo 12Firefox Soporte completo 40IE Sin soporte NoOpera Soporte completo 31Safari Soporte completo 9WebView Android Soporte completo 44Chrome Android Soporte completo 44Firefox Android Soporte completo 40Opera Android Soporte completo 32Safari iOS ? Samsung Internet Android Soporte completo 4.0nodejs Soporte completo Si
Shorthand notation for object literalsChrome Soporte completo 43Edge Soporte completo 12Firefox Soporte completo 33IE Sin soporte NoOpera Soporte completo 30Safari Soporte completo 9WebView Android Soporte completo 43Chrome Android Soporte completo 43Firefox Android Soporte completo 33Opera Android Soporte completo 30Safari iOS ? Samsung Internet Android Soporte completo 4.0nodejs Soporte completo Si
Template literalsChrome Soporte completo 41Edge Soporte completo 12Firefox Soporte completo 34IE Sin soporte NoOpera Soporte completo 28Safari Soporte completo 9WebView Android Soporte completo 41Chrome Android Soporte completo 41Firefox Android Soporte completo 34Opera Android Soporte completo 28Safari iOS Soporte completo 9Samsung Internet Android Soporte completo 4.0nodejs Soporte completo 4.0.0
Trailing commasChrome Soporte completo 1Edge Soporte completo 12Firefox Soporte completo 1IE Soporte completo 9Opera Soporte completo SiSafari Soporte completo SiWebView Android Soporte completo 1Chrome Android Soporte completo 18Firefox Android Soporte completo 4Opera Android Soporte completo SiSafari iOS Soporte completo SiSamsung Internet Android Soporte completo 1.0nodejs Soporte completo Si

Leyenda

Soporte completo  
Soporte completo
Sin soporte  
Sin soporte
Compatibilidad desconocida  
Compatibilidad desconocida
Experimental. Esperar que el comportamiento cambie en el futuro.
Experimental. Esperar que el comportamiento cambie en el futuro.
El usuario debe de habilitar explícitamente esta característica.
El usuario debe de habilitar explícitamente esta característica.

Progreso de la implementación

The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in Test262, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.

Ver también