EcmaScript 10 - JavaScript de este a帽o (ES2019)

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 # .



KDPV: Im谩n amarillo con la inscripci贸n "JS ES10" en la pantalla del monitor - de kasper.green & elfafeya.art
Foto por: kasper.green; Im谩n amarillo: elfafeya.art & kasper.green


Contenido


Cinco etapas #


Etapa 4 - Final #


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 .




Etapa 3 - Prelanzamiento #


# : 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 # ;


Resultados #




Cinco etapas


Etapa 0Strawman Basting Una idea que se puede implementar a trav茅s del complemento Babel .


Etapa 1Propuesta Propuesta Verificaci贸n de la viabilidad de la idea.


Etapa 2Borrador Borrador Inicio del desarrollo de la especificaci贸n.


Etapa 3Candidato Candidate Preview Specification.;


Etapa 4Finalizado 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) { //    return false; } } 


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 { //   return false; } } 



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) // "Symbol(Symbol description)" 

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 // "Symbol description" 

Si no se especifica la descripci贸n, volver谩 - undefined :


 const without_description_symbol_link = Symbol() without_description_symbol_link.description // undefined const empty_description_symbol_link = Symbol('') empty_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 鈥嬧媏n 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.



 //   function () { console.log('My Function!'); }.toString(); // function () { console.log('My Function!'); } //     Number.parseInt.toString(); // function parseInt() { [native code] } //     function () { }.bind(0).toString(); // function () { [native code] } //     Symbol.toString(); // function Symbol() { [native code] } //     Function().toString(); // function anonymous() {} //    - function* () { }.toString(); // function* () { } // .call   ,   ,  Function.prototype.toString.call({}); // Function.prototype.toString requires that 'this' be a Function" 



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]]) // {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 鈥  ' ] ] ] ] ] // 0 鈥     deep_deep_array.flat(0) //  ["鈮0 鈥  ", Array(2)] // 1 鈥    deep_deep_array.flat() //  [" ", " ", Array(2)] deep_deep_array.flat(2) //  [" ", " ", " ", Array(2)] deep_deep_array.flat(100500) // [" ", " ", " ", " ", " "] 

.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]) // ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] 

Usando solo .flat() y .map() , el ejemplo se puede reescribir as铆:


  ['Hello', 'World'].map(word => [...word]).flat() // ["H", "e", "l", "l", "o", "W", "o", "r", "l", "d"] 

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 = '鈥s 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)); // (age: 10) 鈫 Sorry. Content not for you echo strval(new AdultContent(25)); // (age: 25) 鈫 鈥s dummy example content (鈥)(鈥) 鈥3 only for adults鈥 $ObjectAdultContent = new AdultContent(32); echo $ObjectAdultContent->content; // (age: 32) 鈫 鈥s dummy example content (鈥)(鈥) 鈥3 only for adults鈥 ?> 

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 (" # " 鈥攍attice, hash) formara parte de la sintaxis.


El ejemplo anterior en ES 10 se puede reescribir de la siguiente manera:


 export default class AdultContent { //    #age = 0 #adult_content = '鈥s dummy example content (鈥)(鈥) 鈥3 (.)(.) only for adults鈥' constructor(age) { this.#setAge(age) } //    static #userIsAdult(age) { return age > 18 } //   get content () { return `(age: ${this.#age}) 鈫 ` + this.#allowed_content } //   get #allowed_content() { if(AdultContent.userIsAdult(this.age)){ return this.#adult_content } else { return 'Sorry. Content not for you.' } } //   #setAge(age) { this.#age = age } toString () { return this.#content } } const AdultContentForKid = new AdultContent(10) console.log(String(AdultContentForKid)) // (age: 10) 鈫 Sorry. Content not for you. console.log(AdultContentForKid.content) // (age: 10) 鈫 Sorry. Content not for you. const AdultContentForAdult = new AdultContent(25) console.log(String(AdultContentForAdult)) // (age: 25) 鈫 鈥s dummy example content (鈥)(鈥) 鈥3 (.)(.) only for adults鈥 console.log(AdultContentForAdult.content) // (age: 25) 鈫 鈥s dummy example content (鈥)(鈥) 鈥3 (.)(.) only for adults鈥 

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&nbsp;unexpected token est谩 lanzando un SyntaxError: Invalid or&nbsp;unexpected token en una SyntaxError: Invalid or&nbsp;unexpected token similar


Grandes n煤meros con BigInt


https://github.com/tc39/proposal-bigint


soporte de navegador

Soporte de navegador para primitiva BigInt ()


El entero m谩ximo que se puede usar de forma segura en JavaScript (2鈦德 - 1):


 console.log(Number.MAX_SAFE_INTEGER) // 9007199254740991 

BigInt es necesario para usar n煤meros de precisi贸n arbitrarios.


Este tipo se declara de varias maneras:


 //  'n'       910000000000000100500n // 910000000000000100500n //      BigInt()   BigInt( 910000000000000200500 ) // 910000000000000200500n //     -  BigInt( "910000000000000300500" ) // 910000000000000300500n //      1642  BigInt( "" ) \\ 

Este es un nuevo tipo primitivo:


 typeof 123; // 鈫 'number' typeof 123n; // 鈫 'bigint' 

Se puede comparar con n煤meros ordinarios:


 42n === BigInt(42); // 鈫 true 42n == 42; // 鈫 true 

Pero las operaciones matem谩ticas deben llevarse a cabo dentro de un tipo:


 20000000000000n/20n // 1000000000000n 20000000000000n/20 // Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions 

Unary menos es compatible, unary plus devuelve un error:


  -2n // -2n +2n // Uncaught TypeError: Cannot convert a BigInt value to a number 


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:


 //      globalThis.Array(1,2,3) // [1, 2, 3] //        globalThis.myGLobalSettings = { it_is_cool: true } //        globalThis.myGLobalSettings // {it_is_cool: true} 



import(dynamic)


https://github.com/tc39/proposal-dynamic-import


soporte de navegador

Soporte de navegador para importaciones din谩micas


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 () => { //   await    const module = await import(`./events_scripts/supperButtonClickEvent.js`) module.clickEvent() }) 

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") // Uncaught SyntaxError: Unexpected identifier 



import.meta: metainformaci贸n sobre el m贸dulo cargado.


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); // { url: "file:///home/user/my-module.js" } 



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() ) // "hello and let us begin." 



.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' //         string_for_searh.match(/o/) // ["o", index: 0, input: "olololo", groups: undefined] //       string_for_searh.match(/o/g) // ["o", "o", "o", "o"] //   string_for_searh.matchAll(/o/) // {_r: /o/g, _s: "olololo"} //        , //      .match    for(const item of string_for_searh.matchAll(/o/)) { console.log(item) } // ["o", index: 0, input: "olololo", groups: undefined] // ["o", index: 2, input: "olololo", groups: undefined] // ["o", index: 4, input: "olololo", groups: undefined] // ["o", index: 6, input: "olololo", groups: undefined] 

El argumento debe ser una expresi贸n regular; de lo contrario, se generar谩 una excepci贸n:


 'olololo'.matchAll('o') // Uncaught TypeError: o is not a regexp! 







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


Material en ingles Versi贸n actual del est谩ndar Ecma-262


Material en ingles Borrador de la pr贸xima versi贸n del est谩ndar Ecma-262


ECMAScript


Nuevos # campos de clase privada en JavaScript


Art铆culo sobre Habr茅 Descripci贸n general de los est谩ndares ES7, ES8 y ES9


Shebang


Art铆culo sobre Habr茅 BigInt - aritm茅tica larga en JavaScript


Art铆culo sobre Habr茅 Ruta del m贸dulo JavaScript


Material en ingles 驴Por qu茅 no privado x


Art铆culo sobre Habr茅 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 # ;


KDPV alternativo con un im谩n amarillo de elfafeya.art
Foto por: kasper.green; Im谩n amarillo: elfafeya.art & kasper.green

Source: https://habr.com/ru/post/437806/


All Articles