La estandarización de JS ha cambiado a un ciclo de actualización de un año, y el comienzo del año es un buen momento para descubrir qué nos espera en el aniversario: ¡la décima edición de EcmaScript!
ES 9 es la versión actual de la especificación .
ES 10 todavía es un borrador .
Hasta la fecha, la Etapa 4 # tiene solo algunas sugerencias.
Y en la Etapa 3 # - ¡una docena entera!
De estos, en mi opinión, los más interesantes son los campos privados de clases # , gramática shebang para scripts # , números de precisión arbitraria # , acceso al contexto global # e importaciones dinámicas # .

Foto por: kasper.green; Imán amarillo: elfafeya.art & kasper.green
Contenido
• catch
: el argumento se ha convertido en opcional # ;
• Symbol().description
: acceso a la descripción del símbolo # ;
• ' EcmaScript'
: compatibilidad mejorada con el formato JSON # ;
• .toString()
- método prototipo actualizado # .
• Object.fromEntries()
: creación de un objeto a partir de una matriz de pares: clave \ valor # ;
• .flat()
y .flatMap()
son métodos prototipo # array .
• #
: todo es privado en las clases, a través de octotorp # ;
• #!/usr/bin/env node
- gramática shebang para scripts # ;
• BigInt()
: una nueva primitiva para números de precisión arbitrarios # ;
• globalThis
: una nueva forma de acceder al contexto global # ;
• import(dynamic)
: importación dinámica # ;
• import.meta
: metainformación sobre el módulo cargado # ;
• JSON.stringify()
: corrección del método # ;
• RegExp
- características en desuso # ;
• .trimStart()
y .trimEnd()
- métodos de cadena prototipo # ;
• .matchAll()
- .match()
con la bandera global # ;
Cinco etapas
Etapa 0 ↓ Strawman Basting Una idea que se puede implementar a través del complemento Babel .
Etapa 1 ↓ Propuesta Propuesta Verificación de la viabilidad de la idea.
Etapa 2 ↓ Borrador Borrador Inicio del desarrollo de la especificación.
Etapa 3 ↓ Candidato Candidate Preview Specification.;
Etapa 4 ֍ Finalizado Se completa la versión final de la especificación para este año.
Solo consideraremos la Etapa 4 , el estándar de facto.
Y la Etapa 3 , que está a punto de formar parte de ella.
֍ Etapa 4
Estos cambios ya son estándar.
Argumento opcional para catch
https://github.com/tc39/proposal-optional-catch-binding
Antes de ES 10, el catch
requería un argumento requerido para recopilar información de error, incluso si no se usaba:
function isValidJSON(text) { try { JSON.parse(text); return true; } catch(unusedVariable) {

Edge aún no se ha actualizado a ES 10, y se espera que se bloquee con un error.
Comenzando con la edición ES 10, los paréntesis pueden omitirse y la catch
se convertirá en dos gotas de agua como try
.

Mi Chrome ya se ha actualizado a ES 10 y, en algunos lugares, a la Etapa 3 . Otras capturas de pantalla serán de Chrome
código fuente function isValidJSON(text) { try { JSON.parse(text); return true; } catch {
Acceda a descripciones de enlaces simbólicos
https://tc39.imtqy.com/proposal-Symbol-description/
Se puede obtener indirectamente una descripción de enlace simbólico utilizando el método toString ():
const symbol_link = Symbol("Symbol description") String(symbol_link)
Comenzando con ES 10, los caracteres tienen una propiedad de descripción que es de solo lectura. Le permite obtener una descripción del símbolo sin ningún baile con una pandereta:
symbol_link.description
Si no se especifica la descripción, volverá - undefined
:
const without_description_symbol_link = Symbol() without_description_symbol_link.description
Cuerdas EcmaScript compatibles con JSON
https://github.com/tc39/proposal-json-superset
EcmaScript, antes de su décima edición, afirma que JSON es un subconjunto de JSON.parse
, pero esto no es cierto.
Las líneas JSON pueden contener separadores de línea sin blindaje U+2028
SEPARADOR DE LÍNEA y párrafos U+2029
SEPARADOR DE PÁRRAFO .
ECMAScript se alinea hasta la décima versión - no.
Si llama a eval()
en Edge con la cadena "\u2029"
,
se comporta como si hiciéramos un salto de línea, justo en el medio del código:

Con las líneas ES 10, todo está bien:

Refinamiento del método prototipo .toString()
http://tc39.imtqy.com/Function-prototype-toString-revision/
Cambiar objetivos- eliminar requisito incompatible hacia atrás:
Si la implementación no puede crear una cadena de código fuente que cumpla con estos criterios, debe devolver una cadena para la cual eval arrojará una excepción con un error de sintaxis.
aclarar un requisito de "funcionalmente equivalente";
estandarizar la representación de cadena de funciones incorporadas y objetos host;
aclarar los requisitos de presentación basados en las "características reales" de un objeto;
asegúrese de que el análisis de la cadena contenga el mismo cuerpo de función y la misma lista de parámetros que el original;
para las funciones definidas usando el código ECMAScript, toString debería devolver un fragmento del texto fuente desde el comienzo del primer token hasta el final del último token correspondiente a la construcción gramatical correspondiente;
para objetos funcionales integrados, toString no debe devolver nada más que una función nativa;
para los objetos llamados que no fueron definidos usando el código ECMAScript, toString debe devolver una función Native;
para funciones creadas dinámicamente (constructores de funciones o generadores) toString debe sintetizar el texto fuente;
para todos los demás objetos, toString debería lanzar una excepción TypeError.
Crear un objeto usando el método Object.fromEntries()
https://github.com/tc39/proposal-object-from-entries
trabaja en cromo
Análogo de _.fromPairs
de lodash
:
Object.fromEntries([['key_1', 1], ['key_2', 2]])
Matrices unidimensionales con .flat()
y .flatMap()
https://github.com/tc39/proposal-flatMap
trabaja en cromo
La matriz adquirió los prototipos .flat()
y .flatMap()
, que generalmente son similares a las implementaciones de lodash , pero aún tienen algunas diferencias. Argumento opcional: establece la profundidad máxima de recorrido del árbol:
const deep_deep_array = [ '≥0 — ', [ '≥1 — ', [ '≥2 — ', [ '≥3 — ', [ '≥4 — ' ] ] ] ] ]
.flatMap()
equivalente a llamar consecutivamente .map().flat()
. La función de devolución de llamada pasada al método debe devolver una matriz que pasará a formar parte de una matriz plana común:
['Hello', 'World'].flatMap(word => [...word])
Usando solo .flat()
y .map()
, el ejemplo se puede reescribir así:
['Hello', 'World'].map(word => [...word]).flat()
También tenga en cuenta que .flatMap()
, a diferencia de .flat()
no tiene configuraciones de profundidad de rastreo. Entonces solo el primer nivel estará pegado.
֍ Etapa 3
Propuestas que han surgido del estado de borrador, pero que aún no han ingresado a la versión final de la norma.
Privado \ estática \ métodos públicos \ propiedades \ atributos de clases
https://github.com/tc39/proposal-class-fields
https://github.com/tc39/proposal-private-methods
https://github.com/tc39/proposal-static-class-features
En algunos idiomas hay un acuerdo para llamar a métodos privados con un espacio visible (" _ " - tal pieza, es posible que conozca este signo con el nombre incorrecto - subrayado) .
Por ejemplo, así:
<?php class AdultContent { private $_age = 0; private $_content = '…is dummy example content (•)(•) —3 (.)(.) only for adults…'; function __construct($age) { $this->_age = $age; } function __get($name) { if($name === 'content') { return " (age: ".$this->_age.") → ".$this->_getContent()."\r\n"; } else { return 'without info'; } } private function _getContent() { if($this->_contentIsAllowed()) { return $this->_content; } return 'Sorry. Content not for you.'; } private function _contentIsAllowed() { return $this->_age >= 18; } function __toString() { return $this->content; } } echo "<pre>"; echo strval(new AdultContent(10));
Déjame recordarte: esto es solo un acuerdo. Nada impide usar el prefijo para otros fines, usar un prefijo diferente o no usarlo en absoluto.
Personalmente, estoy impresionado con la idea de usar un espacio visible como prefijo para las funciones que devuelven this
. Entonces se pueden combinar en una cadena de llamadas.
Los desarrolladores de la especificación EcmaScript fueron más allá e hicieron que el prefijo octotorp (" # " —lattice, hash) formara parte de la sintaxis.
El ejemplo anterior en ES 10 se puede reescribir de la siguiente manera:
export default class AdultContent {
El ejemplo es innecesariamente complicado para demostrar propiedades privadas, métodos y atributos a la vez. Pero en general, JS - agrada a la vista con su concisión en comparación con la versión de PHP. Sin función privada _... para usted, sin punto y coma al final de la línea, y un punto en lugar de "->" para profundizar en el objeto.
Getters nombrados. Para nombres dinámicos, objetos proxy.
Parecen ser insignificantes, pero después de cambiar a JS, cada vez hay menos ganas de volver a PHP.
Por cierto, los accesos privados solo están disponibles con Babel 7.3.0 y versiones posteriores.
Al momento de escribir, la versión más reciente de npmjs.com es 7.2.2
¡Espero con ansias la Etapa 4!
Shebang Grammar
https://github.com/tc39/proposal-hashbang
Hashbang es una forma en que Unix está familiarizado con la especificación de un intérprete para un archivo ejecutable:
#!/usr/bin/env node // 'use strict'; console.log(1);
#!/usr/bin/env node // export {}; console.log(1);
Chrome SyntaxError: Invalid or unexpected token
está lanzando un SyntaxError: Invalid or unexpected token
en una SyntaxError: Invalid or unexpected token
similar
Grandes números con BigInt
https://github.com/tc39/proposal-bigint
El entero máximo que se puede usar de forma segura en JavaScript (2⁵³ - 1):
console.log(Number.MAX_SAFE_INTEGER)
BigInt es necesario para usar números de precisión arbitrarios.
Este tipo se declara de varias maneras:
Este es un nuevo tipo primitivo:
typeof 123;
Se puede comparar con números ordinarios:
42n === BigInt(42);
Pero las operaciones matemáticas deben llevarse a cabo dentro de un tipo:
20000000000000n/20n
Unary menos es compatible, unary plus devuelve un error:
-2n
globalThis
: una nueva forma de acceder al contexto global
https://github.com/tc39/proposal-global
trabaja en cromo
Dado que las implementaciones de alcance global dependen de un motor en particular, tenía que hacer algo como esto antes:
var getGlobal = function () { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('unable to locate global object'); };
E incluso esta opción no garantizaba que todo funcionara con seguridad.
globalThis
es una forma común para que todas las plataformas accedan al alcance global:
import(dynamic)
https://github.com/tc39/proposal-dynamic-import
Quería variables en las líneas de importación Con importaciones dinámicas, esto se hizo posible:
import(`./language-packs/${navigator.language}.js`)
La importación dinámica es una operación asincrónica. Devuelve una promesa de que, después de cargar el módulo, lo devuelve a la función de devolución de llamada.
Por lo tanto, puede cargar módulos, diferidos cuando sea necesario:
element.addEventListener('click', async () => {
Sintácticamente, esto se parece a una llamada a la función import()
, pero no hereda de Function.prototype
, lo que significa que no tendrá éxito en llamar a través de call
o apply
:
import.call("example this", "argument")
https://github.com/tc39/proposal-import-meta
trabaja en cromo
En el código del módulo cargado, se hizo posible obtener información sobre él. Ahora esta es solo la dirección en la que se cargó el módulo:
console.log(import.meta);
JSON.stringify()
método JSON.stringify()
https://github.com/tc39/proposal-well-formed-stringify
La Sección 8.1 de RFC 8259 requiere que el texto JSON intercambiado fuera de un ecosistema cerrado se codifique utilizando UTF-8, pero JSON.stringify puede devolver cadenas que contienen puntos de código que no están representados en UTF-8 (en particular, puntos de código sustitutos de U + D800 a U + DFFF)
Entonces la línea \uDF06\uD834
después de procesar JSON.stringify () se convierte en \\udf06\\ud834
:
JSON.stringify('\uDF06\uD834') '"\\udf06\\ud834"' JSON.stringify('\uDEAD') '"\\udead"'
Esto no debería ser, y la nueva especificación lo corrige. Edge y Chrome ya se han actualizado.
Características obsoletas de RegExp
https://github.com/tc39/proposal-regexp-legacy-features
Especificación para funciones RegExp heredadas, como el método RegExp.$1
y RegExp.prototype.compile()
.
Métodos de cadena de prototipo .trimStart()
y .trimEnd()
https://github.com/tc39/proposal-string-left-right-trim
trabaja en cromo
Por analogía con los métodos .padStart()
y .padEnd()
, corta el espacio en blanco al principio y al final de la línea, respectivamente:
const one = " hello and let "; const two = "us begin. "; console.log( one.trimStart() + two.trimEnd() )
.matchAll () es un nuevo método de cadena prototipo.
https://github.com/tc39/proposal-string-matchall
trabaja en cromo
Funciona como el método .match()
con la bandera g
activada, pero devuelve un iterador:
const string_for_searh = 'olololo'
El argumento debe ser una expresión regular; de lo contrario, se generará una excepción:
'olololo'.matchAll('o')
Resumen
La etapa 4 trajo más cambios cosméticos. El interés es la etapa 3 . La mayoría de las sugerencias en Chrome ya están implementadas, y las propiedades de los objetos realmente están deseando.
Correcciones en el articulo
Si notó una inexactitud en el artículo, un error o hay algo para complementar, puede escribirme un mensaje personal , pero es mejor usar el repositorio de artículos https://github.com/KasperGreen/es10 usted mismo. Por su contribución activa, otorgaré una medalla de imán amarilla con KDPV.
Materiales relacionados
Versión actual del estándar Ecma-262
Borrador de la próxima versión del estándar Ecma-262
ECMAScript
Nuevos # campos de clase privada en JavaScript
Descripción general de los estándares ES7, ES8 y ES9
Shebang
BigInt - aritmética larga en JavaScript
Ruta del módulo JavaScript
¿Por qué no privado x
Propuesta de ECMAScript: Array.prototype. {Flat, flatMap}
Campos de clase públicos y privados.
JavaScript: el gran todo por qué
UPD (marzo):
Cambió el estado a Etapa - 4 :
• .trimStart()
y .trimEnd()
- métodos de cadena prototipo # ;
• .matchAll()
- .match()
con la bandera global # ;

Foto por: kasper.green; Imán amarillo: elfafeya.art & kasper.green