
La sintaxis de JavaScript es el conjunto de reglas que definen un programa JavaScript correctamente estructurado.
Los ejemplos que se muestran a continuación utilizan la console.log()función presente en la mayoría de los navegadores para la salida de texto estándar .
La biblioteca estándar de JavaScript carece de una función oficial de salida de texto estándar (con la excepción de document.write). Dado que JavaScript se utiliza principalmente para la programación del lado del cliente dentro de los navegadores web modernos , y que casi todos los navegadores web proporcionan la función alert, alerttambién se puede utilizar, pero no es de uso común.
TypeScript , que extiende JavaScript con anotaciones de tipo y características adicionales, tiene la misma sintaxis, así como sus propias características adicionales.
Orígenes

Brendan Eich resumió la ascendencia de la sintaxis en el primer párrafo de la especificación JavaScript 1.1 [ 1 ] [ 2 ] de la siguiente manera:
JavaScript toma prestada la mayor parte de su sintaxis de Java , pero también hereda de Awk y Perl , con cierta influencia indirecta de Self en su sistema de prototipos de objetos.
La sintaxis de JavaScript se deriva principalmente de la sintaxis de Java , que a su vez se deriva de la sintaxis de C y de la sintaxis de C++ .
Lo esencial
Palabras clave
Palabras clave reservadas
Las siguientes palabras son palabras clave.
breakcasecatchclassconstcontinuedebuggerdefaultdeletedoelseenumevalexportextendsfinallyforfunctionifimportininstanceofnewreturnsuperswitchthisthrowtrytypeofusingvarvoidwhilewith
Palabras clave reservadas en modo estricto
Las siguientes palabras son palabras clave en modo estricto.
letimplementsinterfacestaticpackageprivateprotectedpublicyield
Palabras clave reservadas en el código del módulo o en el cuerpo de la función asíncrona.
Las siguientes palabras son palabras clave en el código del módulo o en el cuerpo de la función asíncrona.
await
Valores literales
Las siguientes palabras se refieren a valores literales utilizados por el idioma.
truefalsenull
JavaScript también define las siguientes constantes globales, que no son palabras clave.
NaNInfinityundefined
Palabras clave eliminadas
Las siguientes palabras, asociadas principalmente con Java, fueron eliminadas del estándar ECMAScript 5/6:
abstractbooleanbytechardoublefinalfloatgotointlongnativeshortsynchronizedthrowstransientvolatile
Palabras clave de TypeScript
Las siguientes palabras adicionales son palabras clave en TypeScript.
abstractanyasdeclareinferkeyofmodulenamespaceneverreadonlytypeunknown
Sensibilidad a mayúsculas y minúsculas
JavaScript distingue entre mayúsculas y minúsculas . Es común que el nombre de un constructor comience con una letra mayúscula y el de una función o variable con una letra minúscula.
Ejemplo:
var a = 5 ; console.log ( a ) ; // 5 console.log ( A ) ; // lanza un ReferenceError : A no está definidoEspacios en blanco y punto y coma
A diferencia de C , los espacios en blanco en el código fuente de JavaScript pueden afectar directamente la semántica . Los puntos y coma finalizan las sentencias en JavaScript. Debido a la inserción automática de punto y coma (ASI), algunas sentencias que están bien formadas cuando se analiza un salto de línea se considerarán completas, como si se hubiera insertado un punto y coma justo antes del salto de línea. Algunos expertos recomiendan proporcionar explícitamente los puntos y coma que finalizan las sentencias, ya que esto puede reducir los efectos no deseados de la inserción automática de punto y coma. [ 3 ]
Hay dos problemas: cinco tokens pueden iniciar una declaración o ser la extensión de una declaración completa; y cinco producciones restringidas, donde no se permiten saltos de línea en ciertas posiciones, lo que podría generar un análisis sintáctico incorrecto.
Los cinco tokens problemáticos son el paréntesis de apertura " (", el corchete de apertura " [", la barra inclinada " /", el signo más " +" y el signo menos " -". De estos, el paréntesis de apertura es común en el patrón de expresión de función invocada inmediatamente , el corchete de apertura aparece a veces, mientras que los demás son bastante raros. Un ejemplo:
a = b + c ( d + e ). foo ()// Se trata como: // a = b + c(d + e).foo();con la sugerencia de que la declaración anterior termine con un punto y coma.
Algunos sugieren, en cambio, el uso de punto y coma al principio de las líneas que comienzan con ' (' o ' [', para evitar que la línea se una accidentalmente con la anterior. Esto se conoce como punto y coma defensivo y se emplea porque, de lo contrario, el código podría volverse ambiguo al reorganizarse. Por ejemplo:
a = b + c ( d + e ). foo ()// Se trata como: // a = b + c; // (d + e).foo();En ocasiones, también se utilizan puntos y comas al inicio de las bibliotecas de JavaScript, por si se añaden a otra biblioteca que omita el punto y coma final, ya que esto puede generar ambigüedad en la instrucción inicial. En estos casos, donde la colocación del punto y coma puede ser inusual, quizás sea mejor colocarlo manualmente al final de las instrucciones.
Las cinco producciones restringidas son return, throw, break, continue, y post-incremento/decremento. En todos los casos, insertar puntos y comas no soluciona el problema, pero aclara la sintaxis analizada, facilitando la detección del error. returny throwtoman un valor opcional, mientras que breaky continuetoman una etiqueta opcional. En todos los casos, se recomienda mantener el valor o la etiqueta en la misma línea que la instrucción. Esto suele aparecer en la instrucción return, donde se podría devolver un literal de objeto grande, que podría colocarse accidentalmente comenzando en una nueva línea. Para post-incremento/decremento, existe una posible ambigüedad con pre-incremento/decremento, y nuevamente se recomienda simplemente mantenerlos en la misma línea.
devolver a + b ;// Devuelve indefinido. Se trata como: // return; // a + b; // Debería escribirse como: // return a + b;Comentarios
La sintaxis de los comentarios es la misma que en C++ , Swift y otros lenguajes de programación.
Los comentarios de una sola línea comienzan con //y continúan hasta el final de la línea. También se puede hacer un segundo tipo de comentarios; estos comienzan con /*y terminan con */y se pueden usar para comentarios de varias líneas.
Un tercer tipo de comentario, el comentario hashbang, comienza con #!y continúa hasta el final de la línea. Solo son válidos al inicio de los archivos y están pensados para su uso en entornos CLI . [ 4 ]
# ! Comentario de Hashbang// Comentario de una sola línea/* Comentario de varias líneas */Variables
Las variables en JavaScript estándar no tienen un tipo asociado, por lo que cualquier valor (cada valor tiene un tipo) puede almacenarse en cualquier variable. A partir de ES6 , la sexta versión del lenguaje, las variables podían declararse con varpara variables de ámbito de función, y leto constque son para variables de nivel de bloque . Antes de ES6, las variables solo podían declararse con una varinstrucción. Los valores asignados a variables declaradas con constno se pueden cambiar, pero sus propiedades sí. varya no debería usarse ya que lety constson compatibles con los navegadores modernos. [ 5 ] El identificador de una variable debe comenzar con una letra, un guion bajo ( _), o un signo de dólar ( $), mientras que los caracteres subsiguientes también pueden ser dígitos ( 0-9). JavaScript distingue entre mayúsculas y minúsculas, por lo que los caracteres en mayúscula " A " a " Z " son diferentes de los caracteres en minúscula " a " a " z ".
A partir de JavaScript 1.5, se pueden usar caracteres ISO 8859-1 o Unicode (o secuencias de escape Unicode) en los identificadores. [ 6 ] En ciertas implementaciones de JavaScript, se puede usar el signo arroba ( @ ) en un identificador, pero esto es contrario a las especificaciones y no es compatible con las implementaciones más recientes.\uXXXX
Alcance y elevación
Las variables declaradas con vartienen un alcance léxico a nivel de función , mientras que las que tienen leto consttienen un alcance a nivel de bloque . Dado que las declaraciones se procesan antes de que se ejecute cualquier código, una variable puede asignarse a y usarse antes de ser declarada en el código. [ 7 ] Esto se conoce comoel hoisting , y es equivalente a que las variables sedeclaren anticipadamenteen la parte superior de la función o bloque. [ 8 ]
Con las declaraciones var, let, y const, solo se eleva la declaración; las asignaciones no se elevan. Por lo tanto, una declaración en medio de la función es equivalente a una declaración al principio de la función y una asignación en ese punto en medio de la función. Esto significa que no se puede acceder a los valores antes de que se declaren; no es posible la referencia anticipada . Con , el valor de una variable es hasta que se inicializa. Las variables declaradas con o no se pueden acceder hasta que se hayan inicializado, por lo que hacer referencia a dichas variables antes provocará un error.varx=1varxx=1varundefinedletconst
Las declaraciones de funciones, que declaran una variable y le asignan una función , son similares a las sentencias de variables, pero además de elevar la declaración, también elevan la asignación (como si toda la sentencia apareciera al principio de la función contenedora), y por lo tanto, también es posible la referencia hacia adelante: la ubicación de una sentencia de función dentro de una función contenedora es irrelevante. Esto es diferente de la asignación de una expresión de función a una variable en una sentencia var, let, o .const
Entonces, por ejemplo,
var func = function () { .. } // solo se eleva la declaración function func () { .. } // se elevan tanto la declaración como la asignaciónEl ámbito de bloque se puede producir envolviendo todo el bloque en una función y luego ejecutándola (esto se conoce como el patrón de expresión de función invocada inmediatamente ) o declarando la variable usando la letpalabra clave.
Declaración y asignación
Las variables declaradas fuera de un ámbito son globales . Si una variable se declara en un ámbito superior, los ámbitos secundarios pueden acceder a ella.
Cuando JavaScript intenta resolver un identificador, lo busca en el ámbito local. Si no lo encuentra, lo busca en el siguiente ámbito externo, y así sucesivamente a lo largo de la cadena de ámbitos hasta llegar al ámbito global , donde residen las variables globales. Si aún no lo encuentra, JavaScript generará una ReferenceErrorexcepción.
Al asignar un identificador, JavaScript sigue exactamente el mismo proceso para recuperarlo, excepto que si no se encuentra en el ámbito global , creará la "variable" en el ámbito donde se creó. [ 9 ] Como consecuencia, una variable nunca declarada será global si se le asigna. Declarar una variable (con la palabra clave var) en el ámbito global (es decir, fuera de cualquier cuerpo de función (o bloque en el caso de let/const)), asignar un identificador nunca declarado o agregar una propiedad al objeto global (normalmente window ) también creará una nueva variable global.
Cabe destacar que el modo estricto de JavaScript prohíbe la asignación de una variable no declarada, lo que evita la contaminación del espacio de nombres global.
Ejemplos
Aquí hay algunos ejemplos de declaraciones de variables y ámbito:
var x1 = 0 ; // Una variable global, porque no está en ninguna función let x2 = 0 ; // También global, esta vez porque no está en ningún bloquefunción f () { var z = 'zorros' , r = 'pájaros' ; // 2 variables locales m = 'pez' ; // global, porque no se declaró en ningún lugar antesfunction child () { var r = 'monos' ; // Esta variable es local y no afecta a la variable "pájaros" r de la función padre. z = 'pingüinos' ; // Cierre: La función hija puede acceder a las variables de la función padre. }veinte = 20 ; // Esta variable se declara en la siguiente línea, pero se puede usar en cualquier parte de la función, incluso antes, como aquí var veinte ;hijo (); return x1 + x2 ; // Podemos usar x1 y x2 aquí, porque son globales }f ();console.log ( z ) ; // Esta línea generará una excepción ReferenceError, porque el valor de z ya no está disponible .for ( let i = 0 ; i < 10 ; i ++ ) console . log ( i ); console . log ( i ); // lanza un ReferenceError: i no está definidofor ( const i = 0 ; i < 10 ; i ++ ) console . log ( i ); // lanza un TypeError: Assignment to constant variablefor ( const i of [ 1 , 2 , 3 ]) console . log ( i ); //no generará una excepción. i no se reasigna sino que se recrea en cada iteración.const pi ; // genera un SyntaxError: Falta el inicializador en la declaración constTipos de datos primitivos
El lenguaje JavaScript proporciona seis tipos de datos primitivos :
UndefinedNumberBigIntStringBooleanSymbol
Algunos tipos de datos primitivos también proporcionan un conjunto de valores con nombre que representan los límites de dichos tipos. Estos valores con nombre se describen en las secciones correspondientes a continuación.
Indefinido
El valor "undefined" se asigna a todas las variables no inicializadas y también se devuelve al comprobar propiedades de objetos que no existen. En un contexto booleano, el valor "undefined" se considera falso.
Nota: `undefined` se considera un tipo primitivo genuino. A menos que se convierta explícitamente, el valor `undefined` puede comportarse de forma inesperada en comparación con otros tipos que se evalúan como falsos en un contexto lógico.
let test ; // variable declarada, pero no definida, ... // ... se establece al valor de undefined const testObj = {}; console.log ( test ); // la variable test existe, pero el valor no ... // ... está definido, muestra undefined console.log ( testObj.myProp ); // testObj existe, la propiedad no, ... // ... muestra undefined console.log ( undefined == null ); // tipo no aplicado durante la comprobación, muestra true console.log ( undefined === null ); // tipo aplicado durante la comprobación, muestra falseNota: No existe un literal de lenguaje incorporado para `undefined`. Por lo tanto, no es una forma infalible de comprobar si una variable es `undefined`, porque en versiones anteriores a ECMAScript 5, es válido que alguien escriba ` . Un enfoque más robusto es comparar usando `.(x===undefined)varundefined="I'm defined now";(typeofx==='undefined')
Funciones como esta no funcionarán como se espera:
función isUndefined ( x ) { let u ; return x === u ; } // así... función isUndefined ( x ) { return x === void 0 ; } // ... o esa segunda función isUndefined ( x ) { return ( typeof x ) === "undefined" ; } // ... o esa terceraAquí, llamar isUndefined(my_var)genera un ReferenceError si my_var es un identificador desconocido, mientras que no.typeofmy_var==='undefined'
Número
Los números se representan en binario como números de coma flotante de doble precisión IEEE 754. Si bien este formato ofrece una precisión de casi 16 dígitos significativos , no siempre puede representar con exactitud los números reales, incluidas las fracciones.
Esto se convierte en un problema al comparar o formatear números. Por ejemplo:
console.log ( 0.2 + 0.1 === 0.3 ); // muestra false console.log ( 0.94 - 0.01 ) ; // muestra 0.9299999999999999Como resultado, se debe utilizar una rutina como el método toFixed() para redondear los números siempre que se formateen para su salida .
Los números pueden especificarse en cualquiera de estas notaciones:
345 ; // un "entero", aunque solo hay un tipo numérico en JavaScript 34.5 ; // un número de punto flotante 3.45e2 ; // otro número de punto flotante, equivalente a 345 0b1011 ; // un entero binario igual a 11 0o377 ; // un entero octal igual a 255 0xFF ; // un entero hexadecimal igual a 255, cuyos dígitos están representados por las ... // ... letras AF pueden ser mayúsculas o minúsculasTambién existe un separador numérico, _ (el guion bajo), introducido en ES2021:
// Nota: La sintaxis de Wikipedia aún no admite separadores numéricos 1 _000_000_000 ; // Se usa con números grandes 1 _000_000 .5 ; // Admite decimales 1 _000e1_000 ; // Admite exponentes// Soporte con binario, octal y hexadecimal 0b0000 _0000_0101_1011 ; 0o0001 _3520_0237_1327 ; 0xFFFF _FFFF_FFFF_FFFE ;// Pero los usuarios no pueden usarlos junto a una parte numérica que no sea un dígito, ni al principio ni al final _12 ; // La variable no está definida (el guion bajo la convierte en un identificador de variable) 12 _ ; // Error de sintaxis (no puede estar al final de los números) 12 _ .0 ; // Error de sintaxis (no tiene sentido poner un separador junto al punto decimal) 12. _0 ; // Error de sintaxis 12 e_6 ; // Error de sintaxis (junto a "e", un no dígito. No tiene sentido poner un separador al principio) 1000 ____0000 ; // Error de sintaxis (junto a "_", un no dígito. Solo se permite 1 separador a la vez)Los rangos +∞ , −∞ y NaN (Not a Number) del tipo numérico se pueden obtener mediante dos expresiones de programa :
Infinito ; // infinito positivo (negativo se obtiene con -Infinito, por ejemplo) NaN ; // El valor Not-A-Number, también devuelto como un error en ... // ... conversiones de cadena a númeroInfinito y NaN son números:
typeof Infinity ; // devuelve "número" typeof NaN ; // devuelve "número"Estos tres valores especiales se corresponden y se comportan como los describe la norma IEEE-754 .
El constructor Number (utilizado como función), o un operador unario + o -, pueden utilizarse para realizar conversiones numéricas explícitas:
const myString = "123.456" ; const myNumber1 = Number ( myString ); const myNumber2 = + myString ;Cuando se utiliza como constructor, se crea un objeto contenedor numérico (aunque es de poca utilidad):
const myNumericWrapper = new Number ( 123.456 );Sin embargo, NaN no es igual a sí mismo:
constante nan = NaN ; consola . iniciar sesión ( NaN == NaN ); // consola falsa . iniciar sesión ( NaN === NaN ); // consola falsa . iniciar sesión ( NaN ! == NaN ); // verdadera consola . iniciar sesión ( nan !== nan ); // verdadero// Los usuarios pueden usar los métodos isNaN para comprobar si hay NaN console.log ( isNaN ( " convertido a NaN" ) ); // verdadero console.log ( isNaN ( NaN ) ); // verdadero console.log ( Number.isNaN ( " no convertido" ) ); // falso console.log ( Number.isNaN ( NaN ) ) ; // verdaderoBigInt
En JavaScript, los números regulares se representan con el tipo de punto flotante IEEE 754, lo que significa que los enteros solo se pueden almacenar de forma segura si el valor se encuentra entre Number.MIN_SAFE_INTEGERy Number.MAX_SAFE_INTEGER. [ 10 ] En cambio, BigInts representa enteros de cualquier tamaño, lo que permite a los programadores almacenar enteros demasiado grandes o pequeños para ser representados con el formato IEEE 754. [ 11 ]
Hay dos maneras de declarar un valor BigInt. Se npuede agregar un entero o BigIntse puede usar la función: [ 11 ]
const a = 12345n ; // Crea una variable y almacena un valor BigInt de 12345 const b = BigInt ( 12345 );Cadena
En JavaScript, una cadena" es una secuencia de caracteres. Las cadenas se pueden crear directamente (como literales) colocando la serie de caracteres entre comillas dobles ( ) o simples ( '). Dichas cadenas deben escribirse en una sola línea, pero pueden incluir caracteres de salto de línea escapados (como \n). El estándar de JavaScript permite el carácter de comilla invertida` ( , también conocido como acento grave o acento grave) para entrecomillar cadenas literales multilínea, así como expresiones incrustadas que utilizan la sintaxis . [ 12 ]${expression}
const greeting = "¡Hola, mundo!" ; const anotherGreeting = 'Saludos, gente de la Tierra.' ; const aMultilineGreeting = `Saludos cordiales, John Doe.`// Los literales de plantilla convierten a tipo las expresiones evaluadas y las interpolan en la cadena. const templateLiteral = `Esto es lo que se almacena en anotherGreeting: ${ anotherGreeting } .` ; console . log ( templateLiteral ); // 'Esto es lo que se almacena en anotherGreeting: 'Saludos, gente de la Tierra.'' console . log ( `Tienes ${ Math . floor ( age )=> 18 ? "permitido" : "no permitido" } para ver esta página web` );Se puede acceder a caracteres individuales dentro de una cadena utilizando el método charAt (proporcionado por String.prototype ). Esta es la forma preferida de acceder a caracteres individuales dentro de una cadena, ya que también funciona en navegadores antiguos:
const h = greeting.charAt ( 0 ) ;En los navegadores modernos, se puede acceder a los caracteres individuales dentro de una cadena (como cadenas con un solo carácter) mediante la misma notación que se utiliza para las matrices:
const h = saludo [ 0 ];Sin embargo, las cadenas de JavaScript son inmutables :
saludo [ 0 ] = "H" ; // Falla.Al aplicar el operador de igualdad ("==") a dos cadenas, el resultado es verdadero si las cadenas tienen el mismo contenido, es decir: la misma longitud y la misma secuencia de caracteres (las mayúsculas y minúsculas son importantes para los alfabetos). Por lo tanto:
const x = "World" ; const compare1 = ( "Hello, " + x == "Hello, World" ); // Aquí compare1 contiene true. const compare2 = ( "Hello, " + x == "hello, World" ); // Aquí compare2 contiene ... // ... false ya que los ... // ... primeros caracteres ... // ... de ambos operandos ... // ... no son de la misma mayúscula/minúscula.Las citas del mismo tipo no se pueden anidar a menos que se escapen .
let x = '"¡Hola, mundo!" dijo.' ; // Bien. x = "" ¡Hola , mundo ! " dijo." ; // No está bien. x = "\"¡Hola, mundo!\" dijo." ; // Funciona escapando " con \"El constructor String crea un objeto string (un objeto que encapsula una cadena):
const greeting = new String ( "Hola, mundo!" );Estos objetos tienen un método valueOf que devuelve la cadena primitiva encapsulada en ellos :
const s = new String ( "Hello !" ); typeof s ; // Es 'object'. typeof s . valueOf (); // Es 'string'.La igualdad entre dos objetos String no se comporta como con los tipos de datos primitivos de cadena:
const s1 = new String ( "Hello !" ); const s2 = new String ( "Hello !" ); s1 == s2 ; // Es falso, porque son dos objetos distintos. s1 . valueOf () == s2 . valueOf (); // Es verdadero.Booleano
JavaScript proporciona un tipo de dato booleano con literales verdadero y falso . El operador `typeof` devuelve la cadena "boolean" para estos tipos primitivos . Cuando se utiliza en un contexto lógico, 0 , -0 , null , NaN , undefined y la cadena vacía ( "" ) se evalúan como falsos debido a la conversión automática de tipos . Todos los demás valores (el complemento de la lista anterior) se evalúan como verdaderos , incluidas las cadenas "0" , "false" y cualquier objeto.
Conversión de tipo
La coerción automática de tipos por parte de los operadores de comparación de igualdad ( ==y !=) se puede evitar utilizando los operadores de comparación con comprobación de tipos ( ===y !==).
Cuando se requiere conversión de tipo, JavaScript convierte los operandos Boolean , Number , String u Object de la siguiente manera: [ 13 ]
- Número y cadena
- La cadena se convierte en un valor numérico. JavaScript intenta convertir el literal numérico de la cadena a un valor de tipo Número. Primero, se obtiene un valor matemático a partir del literal numérico de la cadena. Luego, este valor se redondea al número entero más cercano.
- Booleano
- Si uno de los operandos es un valor booleano, el operando booleano se convierte en 1 si es verdadero o en 0 si es falso .
- Objeto
- Si se compara un objeto con un número o una cadena, JavaScript intenta devolver el valor predeterminado del objeto. Para ello, el objeto se convierte a un valor primitivo de tipo cadena o número mediante los métodos ` .valueOf()` o `.toString()` . Si esto falla, se genera un error en tiempo de ejecución.
Conversión de tipo booleano
Douglas Crockford defiende los términos "verdadero" y "falso" para describir cómo se comportan los valores de varios tipos cuando se evalúan en un contexto lógico, especialmente en lo que respecta a los casos límite. [ 14 ] Los operadores lógicos binarios devolvían un valor booleano en las primeras versiones de JavaScript, pero ahora devuelven uno de los operandos en su lugar. Se devuelve el operando izquierdo, si se puede evaluar como : falso , en el caso de la conjunción : ( ), o verdadero , en el caso de la disyunción : ( ); de lo contrario, se devuelve el operando derecho. La coerción automática de tipos por parte de los operadores de comparación puede diferir para los casos de operandos mixtos compatibles con booleanos y números (incluidas cadenas que se pueden evaluar como un número, u objetos que se pueden evaluar como una cadena), porque el operando booleano se comparará como un valor numérico. Esto puede ser inesperado. Una expresión se puede convertir explícitamente a una primitiva booleana duplicando el operador de negación lógica : ( !! ), usando la función Boolean() , o usando el operador condicional : ( ).a && ba || bc ? t : f
// Conversión automática de tipos console.log(true == 2); // false... true → 1 !== 2 ← 2 console.log(false == 2 ) ; // false ... false → 0 !== 2 ← 2 console.log(true == 1 ) ; // true .... true → 1 === 1 ← 1 console.log( false == 0 ) ; // true .... false → 0 === 0 ← 0 console.log ( true == " 2 " ) ; // false ... true → 1 !== 2 ← "2" console.log ( false == " 2" ); // false ... false → 0 !== 2 ← "2" console.log ( true == "1" ) ; // verdadero.... verdadero → 1 === 1 ← "1" consola . iniciar sesión ( falso == "0" ); // verdadero.... falso → 0 === 0 ← "0" consola . iniciar sesión ( falso == "" ); // verdadero.... falso → 0 === 0 ← "" consola . iniciar sesión ( falso == NaN ); // falso... falso → 0 !== NaNconsole.log ( NaN == NaN ); // falso...... NaN no es equivalente a nada, incluido NaN .// Comparación con comprobación de tipos (sin conversión de tipos y valores) console.log ( true === 1 ); // false ...... los tipos de datos no coinciden// Coerción de tipo explícita console.log ( true === !! 2 ); // verdadero... los tipos de datos y los valores coinciden console.log (true === !! 0); // falso... los tipos de datos coinciden, pero los valores difieren console.log( 1 ? verdadero : falso ) ; // verdadero... solo ±0 y NaN son números "falsos" console.log( " 0 " ? verdadero : falso ) ; // verdadero ... solo la cadena vacía es " falsa " console.log ( Booleano ( { })); // verdadero... todos los objetos son "verdaderos "El nuevo operador permite crear un contenedor de objeto para un tipo primitivo booleano. Sin embargo, el operador `typeof` no devuelve un valor booleano para el contenedor, sino un objeto . Dado que todos los objetos se evalúan como verdaderos , se debe usar un método como `.valueOf() ` o `.toString() ` para recuperar el valor encapsulado. Para una conversión explícita al tipo booleano, Mozilla recomienda usar la función `Boolean()` (sin `new` ) en lugar del objeto `Boolean`.
const b = new Boolean ( false ); // Objeto false {} const t = Boolean ( b ); // Booleano true const f = Boolean ( b.valueOf ( )); // Booleano false let n = new Boolean ( b ); // No recomendado n = new Boolean ( b.valueOf ( ) ); // Preferidoif ( 0 || - 0 || "" || null || undefined || b . valueOf () || ! new Boolean () || ! t ) { console . log ( "Nunca esto" ); } else if ([] && {} && b && typeof b === "object" && b . toString () === "false" ) { console . log ( "Siempre esto" ); }Símbolo
Los símbolos son una característica introducida en ES6 . Se garantiza que cada símbolo es un valor único y se pueden usar para la encapsulación . [ 15 ]
Ejemplo:
let x = Symbol ( 1 ); const y = Symbol ( 1 ); x === y ; // => falseconst symbolObject = {}; const normalObject = {};// dado que x e y son únicos, // pueden usarse como claves únicas en un objeto symbolObject [ x ] = 1 ; symbolObject [ y ] = 2 ;symbolObject [ x ]; // => 1 symbolObject [ y ]; // => 2// en comparación con las teclas numéricas normales normalObject [ 1 ] = 1 ; normalObject [ 1 ] = 2 ; // sobrescribe el valor de 1normalObject [ 1 ]; // => 2// cambiar el valor de x no cambia la clave almacenada en el objeto x = Symbol ( 3 ); symbolObject [ x ]; // => indefinido// Cambiar x de nuevo solo crea otro símbolo único x = Symbol ( 1 ); symbolObject [ x ]; // => indefinidoTambién existen símbolos muy conocidos .
Una de ellas es Symbol.iterator; si algo implementa Symbol.iterator, es iterable:
const x = [ 1 , 2 , 3 , 4 ]; // x es un Array x [ Symbol . iterator ] === Array . prototype [ Symbol . iterator ]; // y los Arrays son iterablesconst xIterator = x [ Symbol.iterator ](); // La función [ Symbol.iterator ] debe proporcionar un iterador para x xIterator.next ( ) ; // { value: 1, done: false } xIterator.next ( ) ; // { value: 2, done: false } xIterator.next ( ); // { value: 3, done: false } xIterator.next ( ) ; // { value : 4, done: false } xIterator.next ( ); // { value: undefined, done: true } xIterator.next (); // { value: undefined, done: true }// Los bucles for..of iteran automáticamente los valores for ( const value of x ) { console . log ( value ); // 1 2 3 4 }// Los conjuntos también son iterables: [ Símbolo . iterador ] en Conjunto . prototipo ; // verdaderofor ( const value of new Set ([ 'apple' , 'orange' ])) { console . log ( value ); // "apple" "orange" }Objetos nativos
El lenguaje JavaScript proporciona un conjunto de objetos nativos . Estos objetos nativos se consideran parte de la especificación de JavaScript. Independientemente del entorno JavaScript, este conjunto de objetos siempre debería estar disponible.
Formación
Un Array es un objeto JavaScript prototipado desde el Arrayconstructor diseñado específicamente para almacenar valores de datos indexados por claves enteras. Los Arrays, a diferencia del tipo Object básico, se prototipan con métodos y propiedades para ayudar al programador en tareas rutinarias (por ejemplo, join, slice, y push).
Al igual que en la familia C , los arreglos utilizan un esquema de indexación basado en cero: un valor que se inserta en un arreglo vacío mediante el pushmétodo ocupa el índice 0 del arreglo.
const myArray = []; // Apunta la variable myArray a un Array vacío recién creado . myArray.push ( "hello World" ); // Rellena el siguiente índice vacío, en este caso 0. console.log(myArray [ 0 ] ) ; // Equivalente a console.log("hello World");Los arreglos tienen una lengthpropiedad que siempre será mayor que el índice entero más grande utilizado en el arreglo. Esta propiedad se actualiza automáticamente si se crea una propiedad con un índice aún mayor. Al escribir un número menor en la lengthpropiedad, se eliminarán los índices mayores.
ArraySe puede acceder a los elementos de s utilizando la notación normal de acceso a las propiedades de los objetos:
myArray [ 1 ]; // el segundo elemento en myArray myArray [ "1" ];Las dos opciones anteriores son equivalentes. No es posible utilizar la notación de "punto" ni cadenas con representaciones alternativas del número:
myArray .1 ; // error de sintaxis myArray [ "01" ]; // no es lo mismo que myArray[1]La declaración de un array puede realizarse mediante un Arrayliteral o mediante el Arrayconstructor:
sea miArray ;// Literales de matriz myArray = [ 1 , 2 ]; // longitud de 2 myArray = [ 1 , 2 ,]; // misma matriz - Los usuarios también pueden tener una coma adicional al final// También es posible no rellenar partes del array myArray = [ 0 , 1 , /* hueco */ , /* hueco */ , 4 , 5 ]; // longitud de 6 myArray = [ 0 , 1 , /* hueco */ , /* hueco */ , 4 , 5 ,]; // mismo array myArray = [ 0 , 1 , /* hueco */ , /* hueco */ , 4 , 5 , /* hueco */ ,]; // longitud de 7// Con el constructor myArray = new Array ( 0 , 1 , 2 , 3 , 4 , 5 ); // longitud de 6 myArray = new Array ( 365 ); // un array vacío con longitud 365Los arreglos se implementan de manera que solo los elementos definidos usan memoria; son " arreglos dispersos ". Configurar y solo usa espacio para estos dos elementos, al igual que cualquier otro objeto. El del arreglo seguirá siendo reportado como 58. La longitud máxima de un arreglo es 4,294,967,295 que corresponde al número binario de 32 bits (11111111111111111111111111111111) 2 .myArray[10]='someThing'myArray[57]='somethingOther'length
Se puede utilizar la declaración literal de objeto para crear objetos que se comportan de forma muy similar a los arreglos asociativos en otros lenguajes:
const perro = { color : "marrón" , tamaño : "grande" }; perro [ "color" ]; // da como resultado "marrón" perro . color ; // también da como resultado "marrón"Se pueden usar las declaraciones literales de objetos y matrices para crear rápidamente matrices asociativas, multidimensionales o ambas. (Técnicamente, JavaScript no admite matrices multidimensionales, pero se pueden simular con matrices de matrices).
const cats = [{ color : "brown" , size : "large" }, { color : "black" , size : "small" }]; cats [ 0 ][ "size" ]; // da como resultado "large"const dogs = { rover : { color : "brown" , size : "large" }, spot : { color : "black" , size : "small" }}; dogs [ "spot" ][ "size" ]; // da como resultado "small" dogs . rover . color ; // da como resultado "brown"Fecha
Un Dateobjeto almacena un contador de milisegundos con signo, donde cero representa el 1 de enero de 1970 a las 00:00:00 UT y un rango de ±10⁸ días . Existen varias formas de proporcionar argumentos al Dateconstructor. Tenga en cuenta que los meses comienzan en cero.
new Date (); // crea una nueva instancia de Date que representa la hora/fecha actual. new Date ( 2010 , 2 , 1 ); // crea una nueva instancia de Date que representa 2010-Mar-01 00:00:00 new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // crea una nueva instancia de Date que representa 2010-Mar-01 14:25:30 new Date ( "2010-3-1 14:25:30" ); // crea una nueva instancia de Date a partir de una String.Se proporcionan métodos para extraer campos, así como una herramienta útil toString:
const d = new Date ( 2010 , 2 , 1 , 14 , 25 , 30 ); // 2010-Mar-01 14:25:30;// Muestra '2010-3-1 14:25:30': console . log ( d . getFullYear () + '-' + ( d . getMonth () + 1 ) + '-' + d . getDate () + ' ' + d . getHours () + ':' + d . getMinutes () + ':' + d . getSeconds ());// El método toString integrado devuelve algo como 'Mon 1 March, 2010 14:25:30 GMT-0500 (EST)': console . log ( d );Error
Se pueden crear mensajes de error personalizados utilizando la Errorclase:
lanzar nuevo Error ( "Algo salió mal." );Estas excepciones pueden ser capturadas por bloques try...catch...finally como se describe en la sección sobre manejo de excepciones .
Matemáticas
El objeto Math contiene varias constantes relacionadas con las matemáticas (por ejemplo, π ) y funciones (por ejemplo, coseno). (Tenga en cuenta que el objeto Math no tiene constructor, a diferencia de Array o Date . Todos sus métodos son "estáticos", es decir, métodos de "clase"). Todas las funciones trigonométricas utilizan ángulos expresados en radianes , no en grados ni en grados centesimales .
Expresión regular
/expresión/ . prueba ( cadena ); // devuelve un valor booleano "cadena" . búsqueda ( /expresión/ ); // devuelve un número de posición "cadena" . reemplazo ( /expresión/ , reemplazo );// Aquí hay algunos ejemplos if ( /Tom/ . test ( "Mi nombre es Tom" )) console . log ( "Hola Tom!" ); console . log ( "Mi nombre es Tom" . search ( /Tom/ )); // == 11 (letras antes de Tom) console . log ( "Mi nombre es Tom" . replace ( /Tom/ , "John" )); // == "Mi nombre es John"Clases de personajes
// \d - dígito // \D - no dígito // \s - espacio // \S - no espacio // \w - carácter de palabra // \W - no palabra // [ ] - uno de // [^] - uno que no es // - - rangoif ( /\d/ . test ( '0' )) console . log ( 'Dígito' ); if ( /[0-9]/ . test ( '6' )) console . log ( 'Dígito' ); if ( /[13579]/ . test ( '1' )) console . log ( 'Número impar' ); if ( /\S\S\s\S\S\S\S/ . test ( 'Mi nombre' )) console . log ( 'Formato correcto' ); if ( /\w\w\w/ . test ( 'Tom' )) console . log ( 'Hola Tom' ); if ( /[a-zA-Z]/ . test ( 'B' )) console . log ( 'Letra' );Coincidencia de caracteres
// A...Z a...z 0...9 - alfanumérico // \u0000...\uFFFF - hexadecimal Unicode // \x00...\xFF - hexadecimal ASCII // \t - tabulación // \n - nueva línea // \r - retorno de carro // . - cualquier carácter // | - ORif ( /Tm/ . test ( 'Tom' )) console . log ( 'Hola Tom, Tam o Tim' ); if ( /A|B/ . test ( "A" )) console . log ( 'A o B' );Repetidores
// ? - 0 o 1 coincidencia // * - 0 o más // + - 1 o más // {n} - exactamente n // {n,} - n o más // {0,n} - n o menos // {n,m} - rango de n a mif ( /ab?c/ . test ( "ac" )) console . log ( "OK" ); // coincidencia: "ac", "abc" if ( /ab*c/ . test ( "ac" )) console . log ( "OK" ); // coincidencia: "ac", "abc", "abbc", "abbbc" etc. if ( /ab+c/ . test ( "abc" )) console . log ( "OK" ); // coincidencia: "abc", "abbc", "abbbc" etc. if ( /ab{3}c/ . test ( "abbbc" )) console . log ( "OK" ); // coincidencia: "abbbc" if ( /ab{3,}c/ . test ( "abbbc" )) console . log ( "OK" ); // coincidencia: "abbbc", "abbbbc", "abbbbbc", etc. if ( /ab{1,3}c/ . test ( "abc" )) consola . iniciar sesión ( "Aceptar" ); // coincidencia: "abc", "abbc", "abbbc"Anclas
// ^ - la cadena comienza con // $ - la cadena termina conif ( /^My/ . test ( "My name is Tom" )) console . log ( "¡Hola!" ); if ( /Tom$/ . test ( "My name is Tom" )) console . log ( "¡Hola Tom!" );Subexpresión
// ( ) - agrupa caracteresif ( /water(mark)?/ . test ( "watermark" )) console . log ( "¡Aquí hay agua!" ); // match: "water", "watermark", if ( /(Tom)|(John)/ . test ( "John" )) console . log ( "¡Hola Tom o John!" );Banderas
// /g - global // /i - ignorar mayúsculas/minúsculas // /m - permitir coincidencias que abarquen varias líneasconsole.log ( "¡Hola Tom!".replace(/Tom/i, "John")); // == "¡Hola John!" console.log("ratatam".replace ( / ta / , " tu " ) ) ; // == " ratutam " console.log ( " ratatam " .replace ( / ta / g , " tu " ) ) ; // == "ratutum"Métodos avanzados
mi_array = mi_cadena . split ( mi_delimitador ); // ejemplo mi_array = "perro,gato,vaca" . split ( "," ); // mi_array==["perro","gato","vaca"];my_array = my_string . match ( my_expression ); // ejemplo my_array = "Comenzamos a las 11:30, 12:15 y 16:45" . match ( /\d\d:\d\d/g ); // my_array==["11:30","12:15","16:45"];Capturar grupos
const myRe = /(\d{4}-\d{2}-\d{2}) (\d{2}:\d{2}:\d{2})/ ; const results = myRe . exec ( "La fecha y hora son 2009-09-08 09:37:08." ); if ( results ) { console . log ( "Coincidencia: " + results [ 0 ]); // Coincidencia completa const my_date = results [ 1 ]; // Primer grupo == "2009-09-08" const my_time = results [ 2 ]; // Segundo grupo == "09:37:08" console . log ( `Es ${ my_time } el ${ my_date } ` ); } else console . log ( "¡No se encontró una fecha válida!" );Función
Cada función en JavaScript es una instancia del Functionconstructor :
// x, y es el argumento. 'return x + y' es el cuerpo de la función, que es el último en la lista de argumentos. const add = new Function ( 'x' , 'y' , 'return x + y' ); add ( 1 , 2 ); // => 3La función de suma anterior también se puede definir mediante una expresión de función:
const add = function ( x , y ) { return x + y ; }; add ( 1 , 2 ); // => 3En ES6, se agregó la sintaxis de función flecha, lo que permite que las funciones que devuelven un valor sean más concisas. También conservan el thisdel objeto global en lugar de heredarlo del lugar donde se llamó o sobre qué se llamó, a diferencia de la function() {}expresión.
const add = ( x , y ) => { return x + y ;}; // Los valores también se pueden devolver implícitamente (es decir, no se necesita una instrucción return) const addImplicit = ( x , y ) => x + y ;agregar ( 1 , 2 ); // => 3 agregarImplícito ( 1 , 2 ) // => 3Para las funciones que necesitan ser elevadas, existe una expresión separada:
función agregar ( x , y ) { return x + y ; } agregar ( 1 , 2 ); // => 3El sistema de elevación permite a los usuarios utilizar la función antes de que sea "declarada":
add ( 1 , 2 ); // => 3, no es una función ReferenceError add ( x , y ) { return x + y ; }Una instancia de función tiene propiedades y métodos.
función restar ( x , y ) { return x - y ; }console.log ( subtract.length ); // = > 2 , aridad de la función (número de argumentos ) console.log ( subtract.toString ( ) ) ;/* "función restar(x, y) { return x - y; }" */Operadores
El operador '+' está sobrecargado : se utiliza para la concatenación de cadenas y la suma aritmética. Esto puede causar problemas al mezclar accidentalmente cadenas y números. Como operador unario, puede convertir una cadena numérica en un número.
// Concatenar 2 cadenas console.log ( ' He' + 'llo' ); // muestra Hello// Sumar dos números console.log ( 2 + 6 ); // muestra 8// Sumar un número y una cadena da como resultado una concatenación (de izquierda a derecha) console.log ( 2 + ' 2 ' ); // muestra 22 console.log ( '$' + 3 + 4 ); // muestra $34, pero se esperaba $7 console.log ( ' $' + ( 3 + 4 )); // muestra $7 console.log ( 3 + 4 + ' 7' ); // muestra 77, los números siguen siendo números hasta que se agrega una cadena// Convierte una cadena a un número usando el operador unario más console.log ( + ' 2 ' === 2 ); // muestra true console.log ( + ' Hola' ); // muestra NaNDe forma similar, el operador '*' está sobrecargado: puede convertir una cadena en un número.
console.log ( 2 + ' 6 ' * 1 ); // muestra 8 console.log ( 3 * ' 7' ); // 21 console.log ( ' 3' * '7' ); // 21 console.log ( ' hello ' * ' world' ) ; // muestra NaNAritmética
JavaScript admite los siguientes operadores aritméticos binarios :
JavaScript admite los siguientes operadores aritméticos unarios :
let x = 1 ; console.log ( ++ x ); // x se convierte en 2; muestra 2 console.log(x++); // muestra 2; x se convierte en 3 console.log( x ) ; // x es 3 ; muestra 3 console.log( x-- ) ; // muestra 3 ; x se convierte en 2 console.log ( x ) ; // muestra 2 ; x es 2 console.log ( -- x ) ; // x se convierte en 1; muestra 1El operador módulo muestra el resto de la división por el módulo. Si intervienen números negativos, el valor devuelto depende del operando.
const x = 17 ; console.log ( x % 5 ) ; // muestra 2 console.log ( x % 6 ) ; // muestra 5 console.log ( -x % 5 ); // muestra -2 console.log ( -x % -5 ) ; // muestra -2 console.log ( x % -5 ) ; // muestra 2Para que siempre se obtenga un número no negativo, los usuarios pueden volver a sumar el módulo y aplicar de nuevo el operador módulo:
const x = 17 ; console.log (( - x % 5 + 5 ) % 5 ); // muestra 3Los usuarios también podrían hacer lo siguiente:
const x = 17 ; console.log ( Math.abs ( -x % 5 ) ) ; // también 3Asignación
Asignación de tipos primitivos
let x = 9 ; x += 1 ; console.log ( x ); // muestra: 10 x *= 30 ; console.log ( x ); // muestra : 300 x /= 6 ; console.log ( x ); // muestra: 50 x - = 3 ; console.log ( x ) ; // muestra: 47 x % = 7 ; console.log ( x ) ; // muestra : 5Asignación de tipos de objetos
/** * Para aprender sobre objetos JavaScript... */ const object_1 = { a : 1 }; // asigna la referencia del objeto recién creado a object_1 let object_2 = { a : 0 }; let object_3 = object_2 ; // object_3 hace referencia al mismo objeto que object_2 object_3 . a = 2 ; message (); // muestra 1 2 2 object_2 = object_1 ; // object_2 ahora hace referencia al mismo objeto que object_1 // object_3 todavía hace referencia a lo que object_2 hacía referencia antes message (); // muestra 1 1 2 object_2 . a = 7 ; // modifica object_1 message (); // muestra 7 7 2objeto_3.a = 5 ; // objeto_3 no cambia objeto_2 mensaje ( ); // muestra 7 7 5objeto_3 = objeto_2 ; objeto_3.a = 4 ; // objeto_3 cambia objeto_1 y objeto_2 mensaje ( ); // muestra 4 4 4/** * Imprime el mensaje en la consola */ function message () { console . log ( object_1 . a + " " + object_2 . a + " " + object_3 . a ); }Tarea de desestructuración
En JavaScript de Mozilla, desde la versión 1.7, la asignación por desestructuración permite asignar partes de estructuras de datos a varias variables a la vez. El lado izquierdo de una asignación es un patrón que se asemeja a un literal de objeto/matriz anidado arbitrariamente que contiene l-lvalues en sus hojas, los cuales recibirán las subestructuras del valor asignado.
let a , b , c , d , e ; [ a , b , c ] = [ 3 , 4 , 5 ]; console . log ( ` ${ a } , ${ b } , ${ c } ` ); // muestra: 3,4,5 e = { foo : 5 , bar : 6 , baz : [ 'Baz' , 'Content' ]}; const arr = []; ({ baz : [ arr [ 0 ], arr [ 3 ]], foo : a , bar : b } = e ); console . log ( ` ${ a } , ${ b } , ${ arr } ` ); // muestra: 5,6,Baz,,,Content [ a , b ] = [ b , a ]; // intercambia el contenido de a y b console . log ( a + ',' + b ); // muestra: 6,5[ a , b , c ] = [ 3 , 4 , 5 ]; // permutaciones [ a , b , c ] = [ b , c , a ]; console . log ( ` ${ a } , ${ b } , ${ c } ` ); // muestra: 4,5,3Operador de extensión/descanso
El estándar ECMAScript 2015 introdujo el ...operador de matriz " ", para los conceptos relacionados de "sintaxis de propagación" [ 16 ] y "parámetros rest". [ 17 ] La propagación de objetos se agregó en ECMAScript 2018.
La sintaxis de propagación ofrece otra forma de desestructurar matrices y objetos. En el caso de las matrices, indica que los elementos deben usarse como parámetros en una llamada a función o como elementos de un literal de matriz. En el caso de los objetos, se puede usar para combinarlos o sobrescribir propiedades.
En otras palabras, " ..." transforma " [...foo]" en " [foo[0], foo[1], foo[2]]", y " this.bar(...foo);" en " this.bar(foo[0], foo[1], foo[2]);", y " { ...bar }" en { prop: bar.prop, prop2: bar.prop2 }.
const a = [ 1 , 2 , 3 , 4 ];// Se puede usar varias veces en la misma expresión.const b = [... a , ... a ]; // b = [1, 2, 3, 4, 1, 2, 3, 4];// Se puede combinar con artículos que no se extienden.const c = [ 5 , 6 , ... a , 7 , 9 ]; // c = [5, 6, 1, 2, 3, 4, 7, 9];// Para comparar, haciendo esto sin el operador de propagación// crea un array anidado.const d = [ a , a ]; // d = [[1, 2, 3, 4], [1, 2, 3, 4]]// Funciona igual con las llamadas a funcionesfunción foo ( arg1 , arg2 , arg3 ) {console.log ( ` ${ arg1 } : ${ arg2 } : $ { arg3 } ` ) ;}// Los usuarios pueden usarlo incluso si pasa más parámetros de los que la función utilizará.foo (... un ); // "1:2:3" → foo(a[0], a[1], a[2], a[3]);// Los usuarios pueden combinarlo con parámetros que no sean de propagación.foo ( 5 , ... a , 6 ); // "5:1:2" → foo(5, a[0], a[1], a[2], a[3], 6);// Para comparar, haciendo esto sin el operador de propagación// Asigna el array a arg1 y nada a los demás parámetros.foo ( a ); // "1,2,3,4:undefined:undefined"const barra = { a : 1 , b : 2 , c : 3 };// Esto copiaría el objetoconst copy = { ... bar }; // copy = { a: 1, b: 2, c: 3 };// Aquí se sobrescribiría la "b".const override = { ... bar , b : 4 }; // override = { a: 1, c: 3, b: 4 }Cuando ...se utiliza en la declaración de una función , indica un parámetro de resto . El parámetro de resto debe ser el último parámetro con nombre en la lista de parámetros de la función. Se le asignará un Arrayque contiene cualquier argumento pasado a la función que exceda los demás parámetros con nombre. En otras palabras, recibe "el resto" de los argumentos pasados a la función (de ahí su nombre).
función foo ( a , b , ... c ) { console . log ( c . length ); }foo ( 1 , 2 , 3 , 4 , 5 ); // "3" → c = [3, 4, 5] foo ( 'a' , 'b' ); // "0" → c = []Los parámetros REST son similares a los objetos de JavaScript arguments, que son objetos tipo array que contienen todos los parámetros (con nombre y sin nombre) de la llamada a la función actual. argumentsSin embargo, a diferencia de estos, los parámetros REST son objetos propiamente dichos , por lo que se pueden usar Arraymétodos como `request` .slice()y `request` directamente sobre ellos..sort()
Comparación
Las variables que hacen referencia a objetos son iguales o idénticas solo si hacen referencia al mismo objeto:
const obj1 = { a : 1 }; const obj2 = { a : 1 }; const obj3 = obj1 ; console . log ( obj1 == obj2 ); //false console . log ( obj3 == obj1 ); //true console . log ( obj3 === obj1 ); //trueVéase también Cadena .
Lógico
JavaScript proporciona cuatro operadores lógicos:
- negación unaria (
NOT = !a) - disyunción binaria (
OR = a || b) y conjunción (AND = a && b) - condicional ternario ( )
c ? t : f
En el contexto de una operación lógica, cualquier expresión se evalúa como verdadera excepto la siguiente :
- Cadenas:
"",'', - Números:
0,-0,NaN, - Especial:
null,undefined, - Booleano:
false.
La función booleana se puede utilizar para convertir explícitamente a un tipo primitivo Boolean:
// Solo las cadenas vacías devuelven falso console.log ( Boolean ( " " ) === false ); console.log ( Boolean ( "false" ) === true ) ; console.log ( Boolean ( " 0" ) === true ) ;// Solo cero y NaN devuelven falso console.log ( Boolean ( NaN ) === false ); console.log ( Boolean ( 0 ) === false ) ; console.log ( Boolean ( -0 ) === false ); // equivalente a -1 * 0 console.log ( Boolean ( -2 ) === true ) ;// Todos los objetos devuelven true console.log ( Boolean ( this ) === true ); console.log ( Boolean ({}) === true ); console.log ( Boolean ( [ ] ) === true ) ;// Estos tipos devuelven false console.log ( Boolean ( null ) === false ); console.log ( Boolean ( undefined ) === false ); // equivalente a Boolean ( )El operador NOT evalúa su operando como un booleano y devuelve la negación. Al usar el operador dos veces seguidas, como una doble negación , se convierte explícitamente una expresión en un tipo primitivo booleano:
console.log ( ! 0 === Booleano ( ! 0 ) ); console.log ( Booleano ( ! 0 ) === !! 1 ) ; console.log ( !! 1 === Booleano ( 1 ) ); console.log ( !! 0 === Booleano ( 0 ) ) ; console.log ( Booleano ( 0 ) === ! 1 ) ; console.log ( ! 1 === Booleano ( ! 1 )); console.log ( ! " " === Booleano ( ! " " ) ) ; console.log ( Booleano ( ! " " ) === !! " s" ); console.log ( !! "s" === Booleano ( " s " ) ) ; console.log ( !! " " === Booleano ( " " ) ) ; console . console.log ( Booleano ( "" ) === ! "s" ) ; console.log ( ! " s" === Booleano ( ! "s" ));El operador ternario también se puede utilizar para la conversión explícita:
console.log ([] == false); console.log([] ? true : false); // “verdadero”, pero la comparación usa [].toString() console.log([0] == false); console.log ( [ 0 ] ? true : false ) ; // [ 0 ] .toString ( ) == " 0 " console.log ( " 0 " == false ) ; console.log ( " 0 " ? true : false ) ; // " 0 " → 0 ... ( 0 == 0 ) ... 0 ← false console.log ([ 1 ] == true ) ; console.log ([ 1 ] ? true : false ) ; // [1].toString() == "1" console.log ( " 1" == true ); console.log ( " 1" ? true : false ); // "1" → 1 ... ( 1 == 1) ... 1 ← true console.log ([ 2 ] ! = true ) ; console.log([2] ? true : false); // [2].toString() == "2" console.log( " 2 " ! = true ) ; console.log ( " 2 " ? true : false ) ; // " 2 " → 2 ... ( 2 != 1) ... 1 ← trueLas expresiones que utilizan características como el post-incremento ( i++) tienen un efecto secundario previsto . JavaScript proporciona evaluación de cortocircuito de expresiones; el operando derecho solo se ejecuta si el operando izquierdo no es suficiente para determinar el valor de la expresión.
console.log ( a || b ); // Cuando a es verdadero, no hay razón para evaluar b. console.log ( a && b ); // Cuando a es falso, no hay razón para evaluar b. console.log ( c ? t : f ) ; // Cuando c es verdadero , no hay razón para evaluar f .En las primeras versiones de JavaScript y JScript , los operadores lógicos binarios devolvían un valor booleano (como la mayoría de los lenguajes de programación derivados de C). Sin embargo, todas las implementaciones contemporáneas devuelven uno de sus operandos:
console.log ( a || b ); // si a es verdadero , devuelve a, de lo contrario devuelve b console.log ( a && b ) ; // si a es falso, devuelve a, de lo contrario devuelve bLos programadores más familiarizados con el comportamiento en C podrían encontrar esta característica sorprendente, pero permite una expresión más concisa de patrones como la fusión de nulos :
const s = t || "(default)" ; // asigna t, o el valor predeterminado, si t es nulo, vacío, etc.Asignación lógica
Bitwise
JavaScript admite los siguientes operadores binarios bit a bit :
Ejemplos:
const x = 11 & 6 ; console.log ( x ) ; // 2JavaScript admite el siguiente operador bit a bit unario :
Asignación bit a bit
JavaScript admite los siguientes operadores de asignación binaria:
Ejemplos:
let x = 7 ; console.log ( x ) ; // 7 x << = 3 ; console.log ( x ) ; // 7->14->28-> 56Cadena
Ejemplos:
let cadena = "ab" + "cd" ; // cadena "abcd" += "e" ; // "abcd"const str2 = "2" + 2 ; // "22", no "4" ni 4.???
El operador más cercano de JavaScript?? es , el "operador de coalescencia nula", que se agregó al estándar en la 11.ª edición de ECMAScript . [ 18 ] En versiones anteriores, se podía usar a través de un complemento de Babel y en TypeScript . Evalúa su operando izquierdo y, si el valor resultante no es "nulo" ( nullo undefined), toma ese valor como su resultado; de lo contrario, evalúa el operando derecho y toma el valor resultante como su resultado.
En el siguiente ejemplo, ase le asignará el valor de bsi el valor de bno es nullo undefined, de lo contrario se le asignará 3.
const a = b ?? 3 ;Antes del operador de coalescencia nula, los programadores usaban el operador lógico OR ( ||). Pero mientras que ??busca específicamente nullo undefined, el ||operador busca cualquier valor falsonull : , undefined, "", 0, NaN, y por supuesto, false.
En el siguiente ejemplo, ase le asignará el valor de bsi el valor de bes verdadero , de lo contrario se le asignará 3.
const a = b || 3 ;Estructuras de control
Declaraciones compuestas
Un par de llaves y una secuencia de instrucciones entre ellas constituyen una instrucción compuesta, que puede utilizarse en cualquier lugar donde se pueda utilizar una instrucción.{ }
Si... de lo contrario
if ( expr ) { //instrucciones; } else if ( expr2 ) { //instrucciones; } else { //instrucciones; }Operador condicional (ternario)
El operador condicional crea una expresión que se evalúa como una de dos expresiones según una condición. Esto es similar a la instrucción `if` , que selecciona una de dos instrucciones para ejecutar según una condición. Es decir, el operador condicional es a las expresiones lo que ` if` es a las instrucciones.
const resultado = condición ? expresión : alternativa ;es lo mismo que:
if ( condición ) { const resultado = expresión ; } else { const resultado = alternativa ; }A diferencia de la instrucción if , el operador condicional no puede omitir su "rama else".
Sentencia switch
La sintaxis de la instrucción switch de JavaScript es la siguiente:
switch ( expr ) { case SOMEVALUE : // instrucciones; break ; case ANOTHERVALUE : // instrucciones para cuando ANOTHERVALUE || ORANOTHERONE // sin instrucción break, se pasa al siguiente caso case ORANOTHERONE : // instrucciones específicas para ORANOTHERONE (es decir, !ANOTHERVALUE && ORANOTHER); break ; // Aquí termina todo. case YETANOTHER : // instrucciones; break ; default : // instrucciones; break ; }break;Es opcional; sin embargo, suele ser necesario, ya que de lo contrario la ejecución del código continuará en el cuerpo del siguiente bloque case. Este comportamiento de ejecución secuencial se puede utilizar cuando el mismo conjunto de instrucciones se aplica en varios casos, creando efectivamente una disyunción entre ellos.- Agregue una instrucción break al final del último caso como medida de precaución, en caso de que se agreguen casos adicionales posteriormente.
- También se pueden utilizar valores literales de cadena para los valores de caso.
- Se pueden utilizar expresiones en lugar de valores.
- El caso predeterminado (opcional) se ejecuta cuando la expresión no coincide con ninguno de los otros casos especificados.
- Se requieren aparatos de ortodoncia.
Bucle for
La sintaxis del bucle for de JavaScript es la siguiente:
for ( inicial ; condición ; instrucción del bucle ) { /* Las instrucciones se ejecutarán cada vez que el bucle for{} se repita, mientras se cumpla la condición */ }o
para ( inicial ; condición ; instrucción de bucle ( iteración )) // una instrucciónPara ... en bucle
La sintaxis de JavaScript for ... in loopes la siguiente:
for ( var property_name in some_object ) { // instrucciones que utilizan some_object[property_name]; }- Itera a través de todas las propiedades enumerables de un objeto.
- Recorre todos los índices utilizados del array, incluyendo todas las propiedades definidas por el usuario, si las hubiera. Por lo tanto, puede ser mejor usar un bucle for tradicional con un índice numérico al iterar sobre arrays.
- Existen diferencias entre los distintos navegadores web con respecto a las propiedades que se reflejarán en la instrucción de bucle `for...in`. En teoría, esto se controla mediante una propiedad de estado interna definida por el estándar ECMAscript llamada "DontEnum", pero en la práctica, cada navegador devuelve un conjunto de propiedades ligeramente diferente durante la introspección. Es útil comprobar una propiedad determinada utilizando . Por lo tanto, añadir un método al prototipo de matriz con puede provocar que los bucles iteren sobre el nombre del método.
if(some_object.hasOwnProperty(property_name)){...}Array.prototype.newMethod=function(){...}for ... in
Bucle while
La sintaxis del bucle while de JavaScript es la siguiente:
mientras ( condición ) { instrucción1 ; instrucción2 ; instrucción3 ; ... }Hacer ... bucle while
La sintaxis de JavaScript do ... while loopes la siguiente:
hacer { instrucción1 ; instrucción2 ; instrucción3 ; ... } mientras ( condición );Con
La instrucción `with` agrega todas las propiedades y métodos del objeto dado al ámbito del siguiente bloque, permitiendo que se haga referencia a ellos como si fueran variables locales.
con ( documento ) { const a = getElementById ( 'a' ); const b = getElementById ( 'b' ); const c = getElementById ( 'c' ); };- Nótese la ausencia de document. antes de cada invocación de getElementById() .
La semántica es similar a la instrucción `with` de Pascal .
Debido a que la disponibilidad de sentencias `with` dificulta el rendimiento del programa y se cree que reduce la claridad del código (ya que cualquier variable dada podría ser en realidad una propiedad de una sentencia ` with` que la contiene ), esta sentencia no está permitida en modo estricto .
Etiquetas
JavaScript admite etiquetas anidadas en la mayoría de las implementaciones. Los bucles o bloques pueden etiquetarse para la instrucción break, y los bucles para continue. Aunque gotoes una palabra reservada, [ 19 ]goto no está implementada en JavaScript.
loop1 : for ( let a = 0 ; a < 10 ; ++ a ) { if ( a === 4 ) break loop1 ; // Se detiene después del cuarto intento console.log ( ' a = ' + a ); loop2 : for ( let b = 0 ; b < 10 ; ++ b ) { if ( b === 3 ) continue loop2 ; // Se omite el número 3 if ( b === 6 ) continue loop1 ; // Continúa el primer bucle, no se muestra 'finished' console.log ( ' b = ' + b ) ; } // Fin de loop2 console.log ( 'finished' ) ; } // Fin de loop1 block1 : { console.log ( ' Hola' ); // Muestra 'Hola' break block1 ; console.log ( 'Mundo' ); // Nunca llegará aquí } goto block1 ; // Error de análisis.Funciones
Una función es un bloque con una lista de parámetros (posiblemente vacía) que normalmente recibe un nombre. Una función puede usar variables locales. Si el usuario sale de la función sin una instrucción `return`, se devuelve el valor `undefined` .
function gcd ( number1 , number2 ) { if ( isNaN ( number1 * number2 )) throw TypeError ( "Argumentos no numéricos no permitidos." ); number1 = Math . round ( number1 ); number2 = Math . round ( number2 ); let difference = number1 - number2 ; if ( difference === 0 ) return number1 ; return difference > 0 ? gcd ( number2 , difference ) : gcd ( number1 , - difference ); } console . log ( gcd ( 60 , 40 )); // 20//En ausencia de paréntesis después del identificador 'gcd' en el lado derecho de la asignación siguiente, //'gcd' devuelve una referencia a la función misma sin invocarla. let mygcd = gcd ; // mygcd y gcd hacen referencia a la misma función. console.log ( mygcd ( 60 , 40 ) ) ; // 20Las funciones son elementos de primera clase y pueden asignarse a otras variables.
El número de argumentos que se pasan al llamar a una función no necesariamente coincide con el número de argumentos en la definición de la función; un argumento con nombre en la definición que no tenga un argumento correspondiente en la llamada tendrá el valor `undefined` (que se puede convertir implícitamente a `false`). Dentro de la función, también se puede acceder a los argumentos a través del objeto `arguments` ; esto permite acceder a todos los argumentos mediante índices (por ejemplo, `arguments` ), incluidos aquellos que superan el número de argumentos con nombre. (Si bien la lista de argumentos tiene una propiedad `arguments`, no es una instancia de `Array` ; no tiene métodos como `.slice()` , `.sort()` , etc.).arguments[0],arguments[1],...arguments[n].length
función add7 ( x , y ) { if ( ! y ) { y = 7 ; } console . log ( x + y + arguments . length ); }; add7 ( 3 ); // 11 add7 ( 3 , 4 ); // 9Los valores primitivos (número, booleano, cadena) se pasan por valor. En el caso de los objetos, se pasa la referencia al objeto.
const obj1 = { a : 1 }; const obj2 = { b : 2 }; function foo ( p ) { p = obj2 ; // Ignora el parámetro real p . b = arguments [ 1 ]; } foo ( obj1 , 3 ); // No afecta a obj1 en absoluto. 3 es un parámetro adicional console . log ( ` ${ obj1 . a } ${ obj2 . b } ` ); // escribe 1 3Las funciones pueden declararse dentro de otras funciones y acceder a las variables locales de la función externa. Además, implementan cierres completos al conservar las variables locales de la función externa incluso después de que esta haya finalizado.
let t = "Top" ; let bar , baz ; function foo () { let f = "foo var" ; bar = function () { console . log ( f ) }; baz = function ( x ) { f = x ; }; } foo (); baz ( "baz arg" ); bar (); // "baz arg" (no "foo var") aunque foo() haya terminado. console . log ( t ); // TopUna función anónima es simplemente una función sin nombre y puede escribirse utilizando notación de función o notación de flecha. En estos ejemplos equivalentes, se pasa una función anónima a la función map y se aplica a cada uno de los elementos del array. [ 20 ]
[ 1 , 2 , 3 ]. map ( function ( x ) { return x * 2 ;); //devuelve [2,4,6] [ 1 , 2 , 3 ]. map (( x ) => { return x * 2 ;}); //mismo resultadoUna función generadora se indica colocando un * después de la palabra clave function y contiene una o más instrucciones yield . Su efecto es devolver un valor y pausar la ejecución en el estado actual. Al declarar una función generadora, se devuelve un iterador. Las llamadas posteriores a iterator.next() reanudan la ejecución hasta la siguiente instrucción yield . Cuando el iterador regresa sin usar una instrucción yield, no hay más valores y la propiedad done del iterador se establece en true . [ 21 ]
Con la excepción de los dispositivos iOS de Apple, los generadores no están implementados para navegadores en dispositivos móviles. [ 22 ]
función * generador () { generar "rojo" ; generar "verde" ; generar "azul" ; }let iterador = generador (); let actual ;while ( current = iterator . next (). value ) console . log ( current ); //muestra rojo, verde y luego azul console . log ( iterator . next (). done ) //muestra trueAsync/await
El operador `await` en JavaScript (y TypeScript) solo se puede usar dentro de una función asíncrona o en el nivel superior de un módulo . Si el parámetro es una promesa , la ejecución de la función asíncrona se reanudará cuando la promesa se resuelva (a menos que la promesa sea rechazada, en cuyo caso se lanzará un error que se puede manejar con el manejo de excepciones normal de JavaScript ). Si el parámetro no es una promesa, el parámetro en sí se devolverá inmediatamente. [ 23 ]
Muchas bibliotecas proporcionan objetos Promise que también se pueden usar con await, siempre que cumplan con la especificación para promesas nativas de JavaScript. Sin embargo, las promesas de la biblioteca jQuery no eran compatibles con Promises/A+ hasta jQuery 3.0. [ 24 ]
A continuación se muestra un ejemplo (modificado a partir de este artículo [ 25 ] ):
interfaz DBResponse { id : string ; rev? : string ; ok? : boolean ; }Interfaz Documento { _id : cadena ; _rev? : cadena ; [ clave : cadena ] : cualquiera ; }interface Database { post ( doc : object ) : Promise < DBResponse > ; get ( id : string ) : Promise < Document > ; }declarar constante db : Base de datos ;función asíncrona createNewDoc ( ) : Promise <Document> { const response : DBResponse = await db.post ( { } ) ; const doc : Document = await db.get ( response.id ) ; return doc ; }función asíncrona principal () : Promise < void > { try { const doc : Document = await createNewDoc (); console . log ( doc ); } catch ( err : Error ) { console . error ( "Error al crear o obtener el documento:" , err ); } }principal ();Node.js versión 8 incluye una utilidad que permite usar los métodos basados en devoluciones de llamada de la biblioteca estándar como promesas. [ 26 ]
objetos
Para mayor comodidad, los tipos se subdividen normalmente en primitivos y objetos . Los objetos son entidades que poseen una identidad (solo son iguales a sí mismas) y que asignan nombres de propiedades a valores (o "ranuras" en la terminología de programación basada en prototipos ). Los objetos pueden considerarse como matrices asociativas o hashes, y a menudo se implementan utilizando estas estructuras de datos. Sin embargo, los objetos poseen características adicionales, como una cadena de prototipos , que las matrices asociativas ordinarias no tienen.
JavaScript tiene varios tipos de objetos integrados, a saber Array, Boolean, Date, , Function, Math, Number, Object, RegExpy String. Otros objetos son "objetos anfitriones", definidos no por el lenguaje, sino por el entorno de ejecución. Por ejemplo, en un navegador, los objetos anfitriones típicos pertenecen al DOM (ventana, formulario, enlaces, etc.).
Creación de objetos
Los objetos se pueden crear mediante un constructor o un literal de objeto. El constructor puede usar una función de objeto integrada o una función personalizada. Por convención, las funciones constructoras reciben un nombre que comienza con mayúscula.
// Constructor const anObject = new Object ();// Objeto literal const objectA = {}; const objectA2 = {}; // A != A2, {}s crean nuevos objetos como copias. const objectB = { index1 : 'valor 1' , index2 : 'valor 2' };// Constructor personalizado (ver más abajo)Los literales de objeto y los literales de matriz permiten crear fácilmente estructuras de datos flexibles:
const myStructure = { name : { first : "Mel" , last : "Smith" }, age : 33 , hobbies : [ "ajedrez" , "correr" ] };Esta es la base de JSON , que es una notación sencilla que utiliza una sintaxis similar a la de JavaScript para el intercambio de datos.
Métodos
Un método es simplemente una función asignada a una propiedad de un objeto. A diferencia de muchos lenguajes orientados a objetos, en JavaScript no existe distinción entre la definición de una función y la de un método. La distinción se produce durante la llamada a la función; una función puede invocarse como un método.
Cuando se llama como método, la variable local estándar `this` se establece automáticamente al valor de la instancia del objeto a la izquierda del punto ( . ). (También existen métodos `call` y `apply` que pueden establecer `this` explícitamente; algunos paquetes, como jQuery, hacen cosas inusuales con `this` ).
En el ejemplo siguiente, Foo se utiliza como constructor. Un constructor no tiene nada de especial; es simplemente una función que inicializa un objeto. Cuando se usa con la palabra clave new , como es habitual, se le asigna un objeto vacío recién creado.
Nótese que en el ejemplo siguiente, Foo simplemente asigna valores a ranuras, algunas de las cuales son funciones. Por lo tanto, puede asignar diferentes funciones a diferentes instancias. En este ejemplo no se utiliza ningún prototipo.
función px () { return this . prefix + "X" ; }función Foo ( yz ) { this . prefix = "a-" ; if ( yz > 0 ) { this . pyz = function () { return this . prefix + "Y" ; }; } else { this . pyz = function () { return this . prefix + "Z" ; }; } this . m1 = px ; return this ; }const foo1 = new Foo ( 1 ); const foo2 = new Foo ( 0 ); foo2 . prefix = "b-" ;console.log ( " foo1 / 2 " + foo1.pyz ( ) + foo2.pyz ( )); // foo1/ 2 aY bZfoo1 . m3 = px ; // Asigna la función misma, no su resultado evaluado, es decir, no px() const baz = { "prefix" : "c-" }; baz . m4 = px ; // No es necesario un constructor para crear un objeto.console.log ( "m1/m3/m4 " + foo1.m1 ( ) + foo1.m3 ( ) + baz.m4 ( ) ) ; // m1/m3 / m4 aX aX cXfoo1 . m2 (); // Lanza una excepción, porque foo1.m2 no existe.Constructores
Las funciones constructoras simplemente asignan valores a las ranuras de un objeto recién creado. Estos valores pueden ser datos u otras funciones.
Ejemplo: Manipulación de un objeto:
función MyObject ( atributoA , atributoB ) { this . atributoA = atributoA ; this . atributoB = atributoB ; }MyObject.staticC = " azul" ; // En la función MyObject, no en el objeto console.log ( MyObject.staticC ) ; // azulconst objeto = nuevo MyObject ( 'rojo' , 1000 );console.log ( object.attributeA ) ; // rojo console.log ( object.attributeB ) ; // 1000console.log ( object.staticC ); // objeto indefinido object.attributeC = new Date ( ) ; // agregar una nueva propiedadeliminar objeto.attributeB ; // elimina una propiedad del objeto // tenga en cuenta que , a diferencia de C++, delete no invoca un "destructor", // sino que elimina una propiedad de un objeto .console.log ( object.attributeB ) ; // indefinidoEl constructor en sí se referencia en la ranura del constructor del prototipo del objeto . Por lo tanto,
function Foo () {} // El uso de 'new' establece ranuras de prototipo (por ejemplo, // x = new Foo() establecería el prototipo de x en Foo.prototype, // y Foo.prototype tiene una ranura de constructor que apunta de vuelta a Foo). const x = new Foo (); // Lo anterior es casi equivalente a const y = {}; y . constructor = Foo ; y . constructor (); // Excepto x . constructor == y . constructor ; // true x instanceof Foo ; // true y instanceof Foo ; // false // El prototipo de y es Object.prototype, no // Foo.prototype, ya que se inicializó con // {} en lugar de new Foo. // Aunque Foo se establece en la ranura del constructor de y, // esto es ignorado por instanceof: solo se considera la ranura del constructor del prototipo de y.Las funciones son objetos en sí mismos, que pueden utilizarse para producir un efecto similar al de las "propiedades estáticas" (según la terminología de C++/Java), como se muestra a continuación. (El objeto función también posee una prototypepropiedad especial, como se explica en la sección "Herencia" más adelante).
La eliminación de objetos rara vez se utiliza, ya que el motor de scripting recolectará la basura de los objetos a los que ya no se hace referencia.
Herencia
JavaScript admite jerarquías de herencia a través de la creación de prototipos al estilo de Self .
En el siguiente ejemplo, la clase Derived hereda de la clase Base . Cuando d se crea como Derived , la referencia a la instancia base de Base se copia a d.base .
Derive no contiene un valor para aBaseFunction , por lo que se recupera de aBaseFunction cuando se accede a aBaseFunction . Esto se hace evidente al cambiar el valor de base.aBaseFunction , lo cual se refleja en el valor de d.aBaseFunction .
Algunas implementaciones permiten acceder al prototipo o establecerlo explícitamente utilizando la ranura __proto__ como se muestra a continuación.
function Base () { this . anOverride = function () { console . log ( "Base::anOverride()" ); };this.aBaseFunction = function () { console.log ( " Base::aBaseFunction() " ) ; } ; }function Derived () { this . anOverride = function () { console . log ( "Derived::anOverride()" ); }; }const base = new Base ( ); Derived.prototype = base ; // Debe estar antes de new Derived() Derived.prototype.constructor = Derived ; // Requerido para que `instanceof` funcioneconst d = new Derived (); // Copia Derived.prototype al slot de prototipo oculto de la instancia d. d instanceof Derived ; // true d instanceof Base ; // truebase . aBaseFunction = function () { console . log ( "Base::aNEWBaseFunction()" ); };d.anOverride ( ); // Derived :: anOverride() d.aBaseFunction ( ) ; // Base :: aNEWBaseFunction ( ) console.log ( d.aBaseFunction == Derived.prototype.aBaseFunction ) ; // trueconsole.log ( d .__ proto__ == base ); // verdadero en implementaciones basadas en Mozilla y falso en muchas otras .A continuación se muestra claramente cómo se copian las referencias a los prototipos al crear una instancia, pero que los cambios en un prototipo pueden afectar a todas las instancias que hacen referencia a él.
función m1 () { return "Uno" ; } función m2 () { return "Dos" ; } función m3 () { return "Tres" ; }función Base () {}Base.prototype.m = m2 ; const bar = new Base ( ); console.log ( " bar.m " + bar.m ( ) ) ; // bar.m Dosfunción Top () { this . m = m3 ; } const t = new Top ();const foo = new Base (); Base.prototype = t ; // No tiene efecto en foo, se copia la *referencia* a t. console.log ( " foo.m " + foo.m ( ) ); // foo.m Dosconst baz = new Base (); console.log ( " baz.m " + baz.m ( ) ); // baz.m Trest.m = m1 ; // Afecta a baz y a cualquier otra clase derivada. console.log ( " baz.m1 " + baz.m ( ) ); // baz.m1 UnoEn la práctica, se utilizan muchas variaciones de estos temas, lo que puede resultar tanto impactante como confuso.
Manejo de excepciones
JavaScript incluye una instrucción try ... catch ... finallypara el manejo de excepciones que permite gestionar los errores en tiempo de ejecución.
La try ... catch ... finallyinstrucción captura las excepciones resultantes de un error o una instrucción throw. Su sintaxis es la siguiente:
try { // Instrucciones en las que podrían lanzarse excepciones } catch ( errorValue ) { // Instrucciones que se ejecutan en caso de excepción } finally { // Instrucciones que se ejecutan posteriormente en cualquier caso }Inicialmente, se ejecutan las instrucciones dentro del bloque try. Si se produce una excepción, el flujo de control del script pasa inmediatamente a las instrucciones del bloque catch, donde la excepción se utiliza como argumento de error. De lo contrario, se omite el bloque catch. Este bloque puede lanzar `throw(errorValue) ` si no desea gestionar un error específico.
En cualquier caso, las instrucciones del bloque finally siempre se ejecutan. Si bien la memoria se libera automáticamente, esto puede utilizarse para limpiar manualmente los recursos (como cerrar archivos o conexiones).
Se puede omitir la cláusula catch o la cláusula finally. El argumento catch es obligatorio.
La implementación de Mozilla permite múltiples sentencias catch, como una extensión del estándar ECMAScript. Siguen una sintaxis similar a la utilizada en Java :
try { instrucción ; } catch ( e if e == "InvalidNameException" ) { instrucción ; } catch ( e if e == "InvalidIdException" ) { instrucción ; } catch ( e if e == "InvalidEmailException" ) { instrucción ; } catch ( e ) { instrucción ; } finally { instrucción ; }En un navegador, el evento onerror se utiliza con mayor frecuencia para capturar excepciones.
onerror = function ( errorValue , url , lineNr ) {...; return true ;};Funciones y métodos nativos
evaluar (expresión)
Evalúa el primer parámetro como una expresión, que puede incluir sentencias de asignación. Se puede hacer referencia a variables locales de las funciones mediante la expresión. Sin embargo, evalrepresenta un grave riesgo de seguridad, ya que permite que un atacante ejecute código arbitrario, por lo que se desaconseja su uso. [ 27 ]
> ( función foo () { ... var x = 7 ; ... console . log ( "val " + eval ( "x + 2" )); ... })(); val 9 indefinidoCaracterísticas específicas de TypeScript
TypeScript , un superconjunto de JavaScript desarrollado por Microsoft , añade las siguientes extensiones de sintaxis a JavaScript:
- Firmas de tipo (anotaciones) y comprobación de tipos en tiempo de compilación
- Inferencia de tipo
- Interfaces
- Tipos enumerados
- Medicamentos genéricos
- Espacios de nombres
- Tuplas
- Gestión explícita de recursos [ 28 ]
Sintácticamente, TypeScript es muy similar a JScript .NET , otra implementación de Microsoft del estándar de lenguaje ECMA-262 que añadió soporte para tipado estático y características clásicas de lenguajes orientados a objetos como clases, herencia, interfaces y espacios de nombres. Otras fuentes de inspiración son Java y C# .
Anotaciones de tipo
TypeScript proporciona tipado estático mediante anotaciones de tipo para permitir la comprobación de tipos en tiempo de compilación .
función agregar ( izquierda : número , derecha : número ) : número { return izquierda + derecha ; }Los tipos primitivos se anotan usando tipos en minúsculas, como number, boolean, bigint, y string. Estos tipos son distintos de sus contrapartes encapsuladasNumber ( , Boolean, etc.), que no pueden tener operaciones realizadas directamente sobre valores (un Numbery numberno se pueden sumar). Además, existen tipos undefinedy nullpara sus respectivos valores.
All other non-primitive types are annotated using their class name, such as Error. Arrays can be written in two different ways which are both syntactically the same: the generic-based syntax Array<T> and a shorthand with T[].
Additional built-in data types are tuples, unions, never, unknown, void, and any:
- An array with predefined data types at each index is a tuple, represented as
[type1, type2, ..., typeN]. - A variable that can hold more than one type of data is a union, represented using the logical OR
|symbol (string | number). - The
nevertype is used when a given type should be impossible to create, which is useful for filtering mapped types. - The
unknowntype is used when dealing with data of an unpredictable shape. Unlikeany, anunknown-typed variable will throw compilation errors when attempting to access properties or methods on that variable without first narrowing the type to something known. This type is often used for catching Errors, handling API responses, or user input.[29] - The
voidtype is used to represent the lack of a type, e.g. from a function with noreturnstatement. - A value of type
anysupports the same operations as a value in JavaScript and minimal static type checking is performed,[30] which makes it suitable for weakly or dynamically typed structures. This is generally discouraged practice and should be avoided when possible.[31]
Type annotations can be exported to a separate declarations file to make type information available for TypeScript scripts using types already compiled into JavaScript. Annotations can be declared for an existing JavaScript library, as has been done for Node.js and jQuery.
The TypeScript compiler makes use of type inference when types are not given. For example, the add method in the code above would be inferred as returning a number even if no return type annotation had been provided. This is based on the static types of left and right being numbers, and the compiler's knowledge that the result of adding two numbers is always a number.
If no type can be inferred because of lack of declarations (such as in a JavaScript module without types), then it defaults to the dynamic any type. Additional module types can be provided using a .d.ts declaration file using the declare module "moduleName" syntax.
Declaration files
When a TypeScript script gets compiled, there is an option to generate a declaration file (with the extension .d.ts) that functions as an interface to the components in the compiled JavaScript. In the process, the compiler strips away all function and method bodies and preserves only the signatures of the types that are exported. The resulting declaration file can then be used to describe the exported virtual TypeScript types of a JavaScript library or module when a third-party developer consumes it from TypeScript.
The concept of declaration files is analogous to the concept of header files found in C/C++.
declarenamespaceArithmetics{add(left:number,right:number):number;subtract(left:number,right:number):number;multiply(left:number,right:number):number;divide(left:number,right:number):number;}Type declaration files can be written by hand for existing JavaScript libraries, as has been done for jQuery and Node.js.
Large collections of declaration files for popular JavaScript libraries are hosted on GitHub in DefinitelyTyped.
Generics
TypeScript supports generic programming using a syntax similar to Java.[32] The following is an example of the identity function.[33]
functionidentity<T>(x:T):T{returnx;}Similar to Java generics, it is possible to bound a type parameter:
functionf<Textendsstring>(x:T):void{// ...}functionprop<T,KextendskeyofT>(obj:T,key:K):T[K]{returnobj[key];}Also, like C++, it is possible to have default generics parameters.
functionmakeArray<T=number>(value:T):T[]{return[value];}Classes
TypeScript uses the same annotation style for class methods and fields as for functions and variables respectively. Compared with vanilla JavaScript classes, a TypeScript class can also implement an interface through the implements keyword, use generic parameters similarly to Java, and specify public and private fields.
classPerson{publicname:string;privateage:number;privatesalary:number;constructor(name:string,age:number,salary:number){this.name=name;this.age=age;this.salary=salary;}toString():string{return`${this.name} (${this.age}) (${this.salary})`;}}Union types
Union types are supported in TypeScript.[34] The values are implicitly "tagged" with a type by the language, and may be retrieved using a typeof call for primitive values and an instanceof comparison for complex data types. Types with overlapping usage (e.g. a slice method exists on both strings and arrays, the plus operator works on both strings and numbers) don't need additional narrowing to use these features.
functionsuccessor(n:number|bigint):number|bigint{// types that support the same operations don't need narrowingreturn++n;}functiondependsOnParameter(v:string|string[]|number){// distinct types need narrowingif(vinstanceofArray){// do something}elseif(typeof(v)==="string"){// do something else}else{// has to be a number}}Enumerated types
TypeScript adds an 'enum' data type to JavaScript.
enumCardSuit{Clubs,Diamonds,Hearts,Spades};letc:CardSuit=CardSuit.Diamonds;By default, enums number members starting at 0; this can be overridden by setting the value of the first:
enumCardSuit{Clubs=1,Diamonds,Hearts,Spades};letc:CardSuit=CardSuit.Diamonds;All the values can be set:
enumCardSuit{Clubs=1,Diamonds=2,Hearts=4,Spades=8};letc:CardSuit=CardSuit.Diamonds;TypeScript supports mapping the numeric value to its name. For example, this finds the name of the value 2:
enumCardSuit{Clubs=1,Diamonds,Hearts,Spades};letsuitName:string=CardSuit[2];alert(suitName);Modules and namespaces
TypeScript distinguishes between modules and namespaces, similar to C++ modules. Both features in TypeScript support encapsulation of classes, interfaces, functions and variables into containers. Namespaces (formerly internal modules) use JavaScript immediately-invoked function expressions to encapsulate code, whereas modules (formerly external modules) use existing JavaScript library patterns (CommonJS or ES Modules).[35]
Resource management
Although TypeScript does not have manual memory management, it has resource management similar to using-with-resource blocks in C# or try-with-resources blocks in Java, or C++resource acquisition is initialization, that automatically close resources without need for finally blocks. In TypeScript, to automatically close an object, it must implement a global interface Disposable, and implement a method Symbol.dispose(). This will automatically be called at the end of scope.[28]
import*asfsfrom'fs';classTempFileimplementsDisposable{#path:string;#handle:number;constructor(path:string){this.#path=path;this.#handle=fs.openSync(path,"w+");}write(data:string):void{fs.writeSync(this.#handle,data);}[Symbol.dispose]():void{fs.closeSync(this.#handle);fs.unlinkSync(this.#path);}}exportfunctiondoSomeWork(){usingfile:TempFile=newTempFile(".some_temp_file.txt");if(someCondition()){// do something here}}See also
References
- ↑"JavaScript 1.1 specification". Archived from the original on 26 February 2017. Retrieved 19 April 2006.
- ↑"Chapter 1. Basic JavaScript". speakingjs.com. Archived from the original on 10 February 2022. Retrieved 22 September 2020.
- ↑Flanagan, David (2006). JavaScript: The definitive Guide. O'Reilly Media, Inc. p. 16. ISBN 978-0-596-10199-2.
Omitting semicolons is not a good programming practice; you should get into the habit of inserting them.
- ↑Farias, Bradley. "Hashbang Grammar". GitHub. Retrieved 13 July 2025.
- ↑"Storing the information you need — Variables - Learn web development | MDN". developer.mozilla.org. 9 May 2023. Retrieved 23 June 2023.
- ↑"Values, Variables, and Literals - MDC". Mozilla Developer Network. 16 September 2010. Archived from the original on 29 June 2011. Retrieved 1 February 2020.
- ↑"JavaScript Hoisting". W3Schools. Archived from the original on 31 March 2022. Retrieved 17 December 2021.
In JavaScript, a variable can be declared after it has been used. In other words; a variable can be used before it has been declared.
- ↑"JavaScript Scoping and HoistingArchived 8 May 2021 at the Wayback Machine", Ben CherryArchived 28 February 2021 at the Wayback Machine, Adequately GoodArchived 8 March 2022 at the Wayback Machine, 8 February 2010
- ↑ECMA-262 5e edition clarified this behavior with the Declarative Environment Record and Object Environment Record. With this formalism, the global object is the Object Environment Record of the global Lexical Environment (the global scope).
- ↑"Number - JavaScript". MDN Web Docs. Retrieved 13 July 2025.
- 12"BigInt - Javascript". MDN Web Docs. Retrieved 13 July 2025.
- ↑"Template literals". MDN Web Docs. Archived from the original on 31 March 2022. Retrieved 4 November 2023.
- ↑"Comparison Operators - MDC Doc Center". Mozilla. 5 August 2010. Archived from the original on 4 May 2012. Retrieved 5 March 2011.
- ↑"The Elements of JavaScript Style". Douglas Crockford. Archived from the original on 17 March 2011. Retrieved 5 March 2011.
- ↑Orendorff, Jason. "ES6 In Depth: Symbols". Mozilla Hacks. Retrieved 13 July 2025.
- ↑"Spread syntax (...) - JavaScript | MDN". developer.mozilla.org. 25 September 2023.
- ↑"rest parameters". 9 September 2024. Archived from the original on 30 May 2018. Retrieved 29 September 2016.
- ↑"ECMAScript 2020 Language Specification". Ecma International. June 2020.
- ↑ECMA-262, Edition 3, 7.5.3 Future Reserved Words
- ↑Yadav, Amitya (4 October 2024). "Named function vs Anonymous Function Impacts". medium.com. Retrieved 19 February 2025.
- ↑"function*". mdm web docs. Retrieved 23 February 2025.
- ↑"ES6 Generators". medium.com. Retrieved 23 February 2025.
- ↑"await - JavaScript (MDN)". Retrieved 2 May 2017.
- ↑"jQuery Core 3.0 Upgrade Guide". Retrieved 2 May 2017.
- ↑"Taming the asynchronous beast with ES7". Retrieved 12 November 2015.
- ↑Foundation, Node.js (30 May 2017). "Node v8.0.0 (Current) - Node.js". Node.js.
- ↑"eval()". MDN Web Docs. Archived from the original on 1 April 2022. Retrieved 29 January 2020.
- 12"Documentation – TypeScript 5.2". www.typescriptlang.org. Archived from the original on 9 August 2024. Retrieved 9 November 2023.
- ↑"Handbook - Basic Types". www.typescriptlang.org. Retrieved 2 July 2025.
- ↑"TypeScript Language Specification p.24"(PDF). Archived from the original(PDF) on 17 November 2013.
- ↑"TypeScript: Documentation – Everyday Types". www.typescriptlang.org/. Archived from the original on 9 August 2024. Retrieved 30 March 2021.
- ↑Turner, Jonathan (18 June 2013). "Announcing TypeScript 0.9". TypeScript Language team blog. Microsoft. Archived from the original on 26 November 2013. Retrieved 18 June 2013.
- ↑"Generics in Typescript". Microsoft. Archived from the original on 5 April 2020. Retrieved 8 April 2020.
- ↑"Handbook - Unions and Intersection Types". www.typescriptlang.org. Retrieved 30 November 2020.
- ↑Sothmann, Sönke (31 January 2014). "An introduction to TypeScript's module system". blog.oio.de. Archived from the original on 1 February 2014. Retrieved 21 February 2014.
Further reading
- Danny Goodman: JavaScript Bible, Wiley, John & Sons, ISBN 0-7645-3342-8.
- David Flanagan, Paula Ferguson: JavaScript: The Definitive Guide, O'Reilly & Associates, ISBN 0-596-10199-6.
- Thomas A. Powell, Fritz Schneider: JavaScript: The Complete Reference, McGraw-Hill Companies, ISBN 0-07-219127-9.
- Axel Rauschmayer: Speaking JavaScript: An In-Depth Guide for Programmers, 460 pages, O'Reilly Media, 25 February 2014, ISBN 978-1449365035. (free online edition)
- Emily Vander Veer: JavaScript For Dummies, 4th Edition, Wiley, ISBN 0-7645-7659-3.
External links
- A re-introduction to JavaScript - Mozilla Developer Center
- JavaScript Loops
- ECMAScript standard references: ECMA-262
- Interactive JavaScript Lessons - example-based
- JavaScript Training
- Mozilla Developer Center Core References for JavaScript versions 1.5, 1.4, 1.3 and 1.2
- Mozilla JavaScript Language Documentation
- JavaScript
- sintaxis del lenguaje de programación