En junio de 2018, el est谩ndar ECMAScript 2015 (
ES6 ) celebr贸 su tercer aniversario. En ES6, en primer lugar, han aparecido muchas caracter铆sticas nuevas de JavaScript, y en segundo lugar, una nueva era de desarrollo del lenguaje comienza con este est谩ndar. Adem谩s, esta fue la 煤ltima versi贸n a gran escala de JS, ya que ahora TC39 aplica el esquema para emitir peque帽os n煤meros anuales del est谩ndar, y no lo vuelve a sacar cada pocos a帽os.

Los 煤ltimos 4 a帽os, ES6, con bastante justificaci贸n, ha atra铆do la atenci贸n universal. El autor del material, cuya traducci贸n publicamos hoy, dice que todo este tiempo, gracias a
Babel , escribi贸 todo el c贸digo utilizando la versi贸n moderna de las especificaciones JS. 脡l cree que ha pasado suficiente tiempo para analizar cr铆ticamente las nuevas caracter铆sticas de ES6. En particular, est谩 interesado en lo que us贸 durante alg煤n tiempo y luego dej贸 de usarlo porque empeor贸 su c贸digo.
Sobre las debilidades de JS
Douglas Crockford, en su
libro JavaScript: Fortalezas, tambi茅n escribi贸 sobre lo que puede considerarse debilidades del lenguaje. Esto es algo que, en su opini贸n, no vale la pena usar. Afortunadamente, entre las innovaciones de ES6 no hay nada tan desagradable como algunas de las viejas caracter铆sticas problem谩ticas de JS, como el operador de igualdad laxa que realiza la conversi贸n de tipo impl铆cita, la funci贸n
eval()
y la instrucci贸n
with
. Las nuevas caracter铆sticas de ES6 est谩n dise帽adas mucho mejor. Sin embargo, hay algunas cosas en 茅l que evito. Esas caracter铆sticas que est谩n en mi lista de "debilidades" de JS est谩n en esta lista por las siguientes razones:
- Son, en esencia, "trampas". Es decir, parece que est谩n dise帽ados para realizar ciertas acciones y, en la mayor铆a de los casos, funcionan seg煤n lo esperado. Sin embargo, a veces se comportan inesperadamente, lo que puede conducir f谩cilmente a errores.
- Aumentan el volumen del idioma a cambio de peque帽os beneficios. Tales oportunidades le dan al desarrollador algunas peque帽as ventajas, pero requieren que alguien que est谩 tratando de descifrar su c贸digo tenga conocimiento de ciertos mecanismos, generalmente ocultos en alg煤n lugar. Esto es doblemente cierto para las capacidades de la API, cuando el uso de esta funci贸n significa que otro c贸digo que interact煤a con el c贸digo escrito por un determinado desarrollador debe conocer la aplicaci贸n de esta funci贸n de la API.
Ahora, guiados por estas consideraciones, hablemos de las debilidades de ES6.
Palabra clave const
Antes de ES6, las variables en JavaScript pod铆an declararse utilizando la palabra clave
var
. Adem谩s, las variables no pod铆an declararse en absoluto, entonces, incluso si se usan en funciones, entran en el 谩mbito global. Las propiedades de los objetos pueden desempe帽ar el papel de variables, y las funciones se declaran utilizando la palabra clave
function
. La palabra clave
var
tiene ciertas caracter铆sticas.
Por lo tanto, le permite crear variables que se agregan al objeto global, o aquellas cuyo alcance est谩 limitado por las funciones. Sin embargo, la palabra clave
var
no presta atenci贸n a los bloques de c贸digo. Adem谩s, puede hacer referencia a una variable declarada utilizando la palabra clave
var
en el c贸digo ubicado antes del comando para su declaraci贸n. Este fen贸meno se conoce como elevar variables. Estas caracter铆sticas, si no se tienen en cuenta, pueden provocar errores. Para rectificar la situaci贸n, ES6 introdujo dos nuevas palabras clave para declarar variables:
let
y
const
. Resolvieron los principales problemas
var
. Es decir, estamos hablando del hecho de que las variables declaradas usando estas palabras clave tienen un alcance de bloque, como resultado, por ejemplo, una variable declarada en un bucle no es visible fuera de ella. Adem谩s, el uso de
let
y
const
no permite acceder a las variables antes de declararlas. Esto dar谩 como resultado un error de
ReferenceError
. Este fue un gran paso adelante. Sin embargo, la aparici贸n de dos nuevas palabras clave, as铆 como sus caracter铆sticas, generaron confusi贸n adicional.
El valor de una variable (constante) declarada con la palabra clave
const
no se puede sobrescribir despu茅s de la declaraci贸n. Esta es la 煤nica diferencia entre
const
y
let
. Esta nueva oportunidad parece 煤til y realmente puede aportar alg煤n beneficio. El problema es la palabra clave
const
s铆. La forma en que se comportan las constantes declaradas al usarlo no corresponde a lo que la mayor铆a de los desarrolladores asocian con el concepto de "constante".
const CONSTANT = 123; // "TypeError: invalid assignment to const `CONSTANT`" CONSTANT = 345; const CONSTANT_ARR = [] CONSTANT_ARR.push(1) // [1] - console.log(CONSTANT_ARR)
El uso de la palabra clave
const
evita que se escriba un nuevo valor en una constante, pero no hace que los objetos a los que hacen referencia tales constantes sean inmutables. Esta caracter铆stica proporciona una protecci贸n deficiente contra cambios de valores cuando se trabaja con la mayor铆a de los tipos de datos. Como resultado, debido al hecho de que el uso de
const
puede generar confusi贸n y al hecho de que si la palabra clave
let
est谩 presente, la presencia de
const
parece redundante, decid铆 usar siempre
let
.
Cadenas de plantillas etiquetadas
La palabra clave
const
es un ejemplo de c贸mo una especificaci贸n crea demasiadas formas de resolver muy pocos problemas. En el caso de cadenas de plantillas etiquetadas, tenemos la situaci贸n opuesta. El comit茅 TC39 consider贸 la sintaxis de tales cadenas como una forma de resolver la interpolaci贸n de cadenas y cadenas multil铆neas. Luego decidieron ampliar esta oportunidad mediante el uso de macros.
Si nunca antes ha visto cadenas de patrones etiquetados, tenga en cuenta que son un poco como
decoradores de cadenas. Aqu铆 hay un ejemplo de c贸mo trabajar con ellos con
MDN :
var person = 'Mike'; var age = 28; function myTag(strings, personExp, ageExp) { var str0 = strings[0]; // "that " var str1 = strings[1]; // " is a " // ( ) // , // , . // var str2 = strings[2]; var ageStr; if (ageExp > 99){ ageStr = 'centenarian'; } else { ageStr = 'youngster'; } return str0 + personExp + str1 + ageStr; } var output = myTag`that ${ person } is a ${ age }`; console.log(output); // that Mike is a youngster
Las cadenas de plantillas etiquetadas no se pueden llamar completamente in煤tiles. Aqu铆 hay una
descripci贸n general de algunos de sus usos. Por ejemplo, son 煤tiles para borrar el c贸digo HTML. Y, en este momento, su aplicaci贸n demuestra el enfoque m谩s preciso en situaciones en las que necesita realizar la misma operaci贸n en todos los datos de entrada de una plantilla de cadena arbitraria. Sin embargo, esto es relativamente raro, puede hacer lo mismo con la API adecuada (aunque dicha soluci贸n es m谩s larga). Y, para resolver la mayor铆a de los problemas, usar la API no ser谩 peor que usar cadenas de plantillas etiquetadas. Esta caracter铆stica no agrega nuevas caracter铆sticas al idioma. Agrega nuevos enfoques para trabajar con datos que deber铆an ser familiares para aquellos que tienen que leer el c贸digo escrito utilizando cadenas de plantillas etiquetadas. Y me esfuerzo por asegurarme de que mi c贸digo permanezca lo m谩s limpio y comprensible posible.
Expresiones de asignaci贸n destructiva redise帽adas
Algunas caracter铆sticas del lenguaje se ven geniales cuando se usan para resolver tareas simples, sin embargo, cuando las tareas se vuelven m谩s complejas, estas caracter铆sticas pueden salirse de control. Por ejemplo, me gusta el operador condicional ternario:
let conferenceCost = isStudent ? 50 : 200
Sin embargo, el c贸digo escrito con su ayuda, se vuelve dif铆cil de entender si, usando este operador, comienza a usar construcciones anidadas:
let conferenceCost = isStudent ? hasDiscountCode ? 25 : 50 : hasDiscountCode ? 100 : 200;
Lo mismo puede decirse de la asignaci贸n destructiva. Este mecanismo le permite extraer los valores de variables de objetos o matrices:
let {a} = {a: 2, b: 3}; let [b] = [4, 5]; console.log(a, b)
Adem谩s, al usarlo, puede cambiar el nombre de las variables, obtener valores anidados, establecer valores predeterminados:
let {a: val1} = {a: 2, b: 3}; let [{b}] = [{a:3, b:4} , {c: 5, d: 6}]; let {c=6} = {a: 2, c: 5}; let {d=6} = {a: 2, c: 5}; console.log(val1, b, c, d)
Todo esto es maravilloso, hasta que se trata de construir expresiones complejas utilizando todas estas caracter铆sticas. Por ejemplo, en la siguiente expresi贸n, se declaran 4 variables:
userName
,
eventType
,
eventDate
y
eventId
. Sus valores se toman de diferentes lugares en la estructura del objeto
eventRecord
.
let eventRecord = { user: { name: "Ben M", email: "ben@m.com" }, event: "logged in", metadata: { date: "10-10-2017" }, id: "123" }; let { user: { name: userName = "Unknown" }, event: eventType = "Unknown Event", metadata: [date: eventDate], id: eventId } = obj;
Comprender dicho c贸digo es casi imposible. Este problema se puede resolver utilizando un c贸digo mucho m谩s legible, si utiliza varias operaciones de desestructuraci贸n o las abandona por completo.
let eventRecord = { user: { name: "Ben M", email: "ben@m.com" }, event: "logged in", metadata: { date: "10-10-2017" }, id: "123" }; let userName = eventRecord.user.userName || 'Unknown'; let eventDate = eventRecord.metadata.date; let {event:eventType='UnknownEvent', id:eventId} = eventRecord;
No tengo una directriz clara que indique que la expresi贸n de la asignaci贸n destructiva necesita ser modificada. Sin embargo, cada vez que miro una expresi贸n similar y no puedo entender instant谩neamente qu茅 problema resuelve, qu茅 variables se usan en 茅l, entiendo que es hora de simplificar el c贸digo para mejorar su legibilidad.
Exportaci贸n predeterminada
ES6 tiene una buena caracter铆stica. Consiste en c贸mo sus desarrolladores abordaron la estandarizaci贸n de lo que se hizo anteriormente con la ayuda de varias bibliotecas, a menudo compitiendo entre s铆. Entonces en la especificaci贸n aparecieron clases, promesas, m贸dulos. Esto es todo lo que la comunidad de desarrolladores de JS usaba antes de ES6, encontr谩ndolo en bibliotecas de terceros. Por ejemplo, los m贸dulos ES6 son un excelente sustituto de lo que se extendi贸 a la guerra de formatos AMD / CommonJS y proporcionan una sintaxis conveniente para organizar las importaciones.
Los m贸dulos ES6 admiten dos formas principales de exportar valores: exportaci贸n con nombre y exportaci贸n predeterminada, o exportaci贸n predeterminada:
const mainValue = 'This is the default export export default mainValue export const secondaryValue = 'This is a secondary value; export const secondaryValue2 = 'This is another secondary value;
Un m贸dulo puede usar varios comandos de exportaci贸n con nombre, pero solo un comando de exportaci贸n predeterminado. Al importar lo que se export贸 utilizando el comando de exportaci贸n predeterminado, en el archivo de importaci贸n, puede asignar cualquier nombre a lo que se exporta de forma predeterminada, ya que no se buscan nombres durante esta operaci贸n. Al usar la exportaci贸n con nombre, debe usar los nombres de las variables de los archivos de exportaci贸n, aunque tambi茅n es posible cambiar el nombre.
// import renamedMainValue from './the-above-example'; // import {secondaryValue} from './the-above-example'; // import {secondaryValue as otherValue} from './the-above-example';
La exportaci贸n predeterminada disfrut贸 de
una atenci贸n especial por parte de los desarrolladores del est谩ndar ES6, y crearon intencionalmente una sintaxis m谩s simple. Sin embargo, en la pr谩ctica, pude descubrir que usar tecnolog铆a de exportaci贸n con nombre es preferible por las siguientes razones.
- Cuando se usa la exportaci贸n con nombre, los nombres de las variables exportadas, por defecto, corresponden a los nombres de las variables importadas, lo que simplifica su b煤squeda de aquellos que no usan herramientas de desarrollo inteligentes.
- Cuando se usan exportaciones con nombre, los programadores que usan herramientas de desarrollo inteligente obtienen caracter铆sticas tan convenientes como la importaci贸n autom谩tica .
- Las exportaciones con nombre le permiten exportar uniformemente desde los m贸dulos todo lo que desee, en las cantidades correctas. La exportaci贸n predeterminada limita al desarrollador a exportar solo un valor 煤nico. Como soluci贸n alternativa, puede aplicar la exportaci贸n de un objeto con varias propiedades. Sin embargo, este enfoque pierde el valor del algoritmo de sacudidas de 谩rboles utilizado para reducir el tama帽o de las aplicaciones JS creadas por algo como webpack. El uso exclusivo de m贸dulos con nombre con nombre simplifica el trabajo.
En general, se puede observar que nombrar entidades es una buena pr谩ctica, ya que le permite identificarlas de manera 煤nica tanto en el c贸digo como en las conversaciones sobre este c贸digo. Por eso uso la exportaci贸n con nombre.
Resumen
Acaba de enterarse de las caracter铆sticas de ES6, que, seg煤n el autor de este material, no tienen 茅xito. Quiz谩s te unas a esta opini贸n, quiz谩s no. Cualquier lenguaje de programaci贸n es un sistema complejo, cuyas capacidades se pueden ver desde diferentes puntos de vista. Sin embargo, esperamos que este art铆culo sea 煤til para todos aquellos que buscan escribir c贸digo claro y de alta calidad.
Estimados lectores! 驴Hay algo en JavaScript moderno que intentes evitar?
