El estándar ECMAScript se ha actualizado una vez más con la incorporación de nuevas funciones en ES2019. Ahora disponible oficialmente en nodo, Chrome, Firefox y Safari, también puede usar Babel para compilar estas funciones en una versión diferente de JavaScript si necesita admitir un navegador más antiguo.
¡Veamos qué hay de nuevo!
Objeto.fromEntries
En ES2017, nos presentaron a Object.entries
. Esta era una función que traducía un objeto a su representación de matriz. Algo como esto:
let students = {
amelia: 20,
beatrice: 22,
cece: 20,
deirdre: 19,
eloise: 21
}
Object.entries(students)
// [
// [ 'amelia', 20 ],
// [ 'beatrice', 22 ],
// [ 'cece', 20 ],
// [ 'deirdre', 19 ],
// [ 'eloise', 21 ]
// ]
Esta fue una adición maravillosa porque permitió que los objetos hicieran uso de las numerosas funciones integradas en el prototipo Array. Cosas como map
, filter
, reduce
, etc. Desafortunadamente, requirió un proceso algo manual para volver a convertir ese resultado en un objeto.
let students = {
amelia: 20,
beatrice: 22,
cece: 20,
deirdre: 19,
eloise: 21
}
// convert to array in order to make use of .filter() function
let overTwentyOne = Object.entries(students).filter(([name, age]) => {
return age >= 21
}) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]
// turn multidimensional array back into an object
let DrinkingAgeStudents = {}
for (let [name, age] of overTwentyOne) {
DrinkingAgeStudents[name] = age;
}
// { beatrice: 22, eloise: 21 }
Object.fromEntries
está diseñado para eliminar ese bucle! Le brinda un código mucho más conciso que lo invita a utilizar métodos de prototipo de matriz en objetos.
let students = {
amelia: 20,
beatrice: 22,
cece: 20,
deirdre: 19,
eloise: 21
}
// convert to array in order to make use of .filter() function
let overTwentyOne = Object.entries(students).filter(([name, age]) => {
return age >= 21
}) // [ [ 'beatrice', 22 ], [ 'eloise', 21 ] ]
// turn multidimensional array back into an object
let DrinkingAgeStudents = Object.fromEntries(overTwentyOne);
// { beatrice: 22, eloise: 21 }
Es importante tener en cuenta que las matrices y los objetos son estructuras de datos diferentes por una razón. Hay ciertos casos en los que cambiar entre los dos causará la pérdida de datos. El siguiente ejemplo de elementos de matriz que se convierten en claves de objeto duplicadas es uno de ellos.
let students = [
[ 'amelia', 22 ],
[ 'beatrice', 22 ],
[ 'eloise', 21],
[ 'beatrice', 20 ]
]
let studentObj = Object.fromEntries(students);
// { amelia: 22, beatrice: 20, eloise: 21 }
// dropped first beatrice!
Al utilizar estas funciones, asegúrese de conocer los posibles efectos secundarios.
Compatibilidad con Object.fromEntries
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 67 | 12.1 | No |
🔍 Podemos utilizar su ayuda. ¿Tiene acceso para probar estas y otras funciones en los navegadores móviles? Deje un comentario con sus resultados: los revisaremos y los incluiremos en el artículo.
Array.prototype.flat
Las matrices multidimensionales son una estructura de datos bastante común, especialmente al recuperar datos. La capacidad de aplanarlo es necesaria. Siempre fue posible, pero no exactamente bonito.
Tomemos el siguiente ejemplo donde nuestro mapa nos deja con una matriz multidimensional que queremos aplanar.
let courses = [
{
subject: "math",
numberOfStudents: 3,
waitlistStudents: 2,
students: ['Janet', 'Martha', 'Bob', ['Phil', 'Candace']]
},
{
subject: "english",
numberOfStudents: 2,
students: ['Wilson', 'Taylor']
},
{
subject: "history",
numberOfStudents: 4,
students: ['Edith', 'Jacob', 'Peter', 'Betty']
}
]
let courseStudents = courses.map(course => course.students)
// [
// [ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
// [ 'Wilson', 'Taylor' ],
// [ 'Edith', 'Jacob', 'Peter', 'Betty' ]
// ]
[].concat.apply([], courseStudents) // we're stuck doing something like this
en viene Array.prototype.flat
. Toma un argumento opcional de profundidad.
let courseStudents = [
[ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
[ 'Wilson', 'Taylor' ],
[ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]
let flattenOneLevel = courseStudents.flat(1)
console.log(flattenOneLevel)
// [
// 'Janet',
// 'Martha',
// 'Bob',
// [ 'Phil', 'Candace' ],
// 'Wilson',
// 'Taylor',
// 'Edith',
// 'Jacob',
// 'Peter',
// 'Betty'
// ]
let flattenTwoLevels = courseStudents.flat(2)
console.log(flattenTwoLevels)
// [
// 'Janet', 'Martha',
// 'Bob', 'Phil',
// 'Candace', 'Wilson',
// 'Taylor', 'Edith',
// 'Jacob', 'Peter',
// 'Betty'
// ]
Tenga en cuenta que si no se proporciona ningún argumento, la profundidad predeterminada es uno. Esto es increíblemente importante porque en nuestro ejemplo eso no aplanaría completamente la matriz.
let courseStudents = [
[ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
[ 'Wilson', 'Taylor' ],
[ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]
let defaultFlattened = courseStudents.flat()
console.log(defaultFlattened)
// [
// 'Janet',
// 'Martha',
// 'Bob',
// [ 'Phil', 'Candace' ],
// 'Wilson',
// 'Taylor',
// 'Edith',
// 'Jacob',
// 'Peter',
// 'Betty'
// ]
La justificación de esta decisión es que la función no es voraz por defecto y requiere instrucciones explícitas para operar como tal. Para una profundidad desconocida con la intención de aplanar completamente la matriz, se puede usar el argumento de Infinity.
let courseStudents = [
[ 'Janet', 'Martha', 'Bob', [ 'Phil', 'Candace' ] ],
[ 'Wilson', 'Taylor' ],
[ 'Edith', 'Jacob', 'Peter', 'Betty' ]
]
let alwaysFlattened = courseStudents.flat(Infinity)
console.log(alwaysFlattened)
// [
// 'Janet', 'Martha',
// 'Bob', 'Phil',
// 'Candace', 'Wilson',
// 'Taylor', 'Edith',
// 'Jacob', 'Peter',
// 'Betty'
// ]
Como siempre, las operaciones codiciosas deben usarse con prudencia y es probable que no sean una buena opción si realmente se desconoce la profundidad de la matriz.
Compatibilidad con Array.prototype.flat
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 67 | 12 | No |
cromo androide | FirefoxAndroid | iOSSafari | IE móvil | Samsung Internet | Vista web de Android |
---|---|---|---|---|---|
75 | 67 | 12.1 | No | No | 67 |
Array.prototype.flatMap
Con la adición de plano también obtuvimos la función combinada de Array.prototype.flatMap
. De hecho, ya hemos visto un ejemplo de dónde esto sería útil arriba, pero veamos otro.
¿Qué pasa con una situación en la que queremos insertar elementos en una matriz? Antes de las adiciones de ES2019, ¿cómo sería eso?
let grades = [78, 62, 80, 64]
let curved = grades.map(grade => [grade, grade + 7])
// [ [ 78, 85 ], [ 62, 69 ], [ 80, 87 ], [ 64, 71 ] ]
let flatMapped = [].concat.apply([], curved) // now flatten, could use flat but that didn't exist before either
// [
// 78, 85, 62, 69,
// 80, 87, 64, 71
// ]
Ahora que tenemos Array.prototype.flat
podemos mejorar este ejemplo ligeramente.
let grades = [78, 62, 80, 64]
let flatMapped = grades.map(grade => [grade, grade + 7]).flat()
// [
// 78, 85, 62, 69,
// 80, 87, 64, 71
// ]
Pero aún así, este es un patrón relativamente popular, especialmente en la programación funcional. Así que tenerlo integrado en el prototipo de matriz es genial. Con flatMap
Podemos hacer esto:
let grades = [78, 62, 80, 64]
let flatMapped = grades.flatMap(grade => [grade, grade + 7]);
// [
// 78, 85, 62, 69,
// 80, 87, 64, 71
// ]
Ahora, recuerde que el argumento predeterminado para Array.prototype.flat
es uno. Y flatMap
es el equivalente a peinarse map
y flat
sin argumento. Entonces flatMap
solo aplanará un nivel.
let grades = [78, 62, 80, 64]
let flatMapped = grades.flatMap(grade => [grade, [grade + 7]]);
// [
// 78, [ 85 ],
// 62, [ 69 ],
// 80, [ 87 ],
// 64, [ 71 ]
// ]
Compatibilidad con Array.prototype.flatMap
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 67 | 12 | No |
cromo androide | FirefoxAndroid | iOSSafari | IE móvil | Samsung Internet | Vista web de Android |
---|---|---|---|---|---|
75 | 67 | 12.1 | No | No | 67 |
String.trimStart y String.trimEnd
Otra buena adición en ES2019 es un alias que hace que algunos nombres de funciones de cadena sean más explícitos. Previamente, String.trimRight
y String.trimLeft
estaban disponibles.
let message = " Welcome to CS 101 "
message.trimRight()
// ' Welcome to CS 101'
message.trimLeft()
// 'Welcome to CS 101 '
message.trimRight().trimLeft()
// 'Welcome to CS 101'
Estas son excelentes funciones, pero también fue beneficioso darles nombres más alineados con su propósito. Quitar el espacio inicial y el espacio final.
let message = " Welcome to CS 101 "
message.trimEnd()
// ' Welcome to CS 101'
message.trimStart()
// 'Welcome to CS 101 '
message.trimEnd().trimStart()
// 'Welcome to CS 101'
Compatibilidad con String.trimStart y String.trimEnd
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 67 | 12 | No |
Encuadernación de captura opcional
Otra buena característica en ES2019 es hacer que un argumento en los bloques try-catch sea opcional. Anteriormente, todos los bloques catch pasaban en la excepción como parámetro. Eso significaba que estaba allí incluso cuando el código dentro del bloque catch lo ignoraba.
try {
let parsed = JSON.parse(obj)
} catch(e) {
// ignore e, or use
console.log(obj)
}
Este ya no es el caso. Si la excepción no se usa en el bloque catch, entonces no es necesario pasar nada.
try {
let parsed = JSON.parse(obj)
} catch {
console.log(obj)
}
Esta es una excelente opción si ya sabe cuál es el error y está buscando qué datos lo desencadenaron.
Compatibilidad con enlace de captura opcional
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 67 | 12 | No |
Cambios en Function.toString()
ES2019 también trajo cambios en la forma Function.toString()
opera. Anteriormente, eliminaba por completo el espacio en blanco.
function greeting() {
const name="CSS Tricks"
console.log(`hello from ${name}`)
}
greeting.toString()
//'function greeting() {nconst name = 'CSS Tricks'nconsole.log(`hello from ${name} //`)n}'
Ahora refleja la verdadera representación de la función en el código fuente.
function greeting() {
const name="CSS Tricks"
console.log(`hello from ${name}`)
}
greeting.toString()
// 'function greeting() {n' +
// " const name="CSS Tricks"n" +
// ' console.log(`hello from ${name}`)n' +
// '}'
Esto es principalmente un cambio interno, pero no puedo evitar pensar que esto también podría facilitar la vida de uno o dos bloggers en el futuro.
Compatibilidad con Function.toString
Cromo | Firefox | Safari | Borde |
---|---|---|---|
75 | 60 | 12 – Parcial | 17 – Parcial |
¡Y ahí lo tienes! Las principales características adiciones a ES2019.
También hay un puñado de otras adiciones que quizás desee explorar. Esos incluyen:
- Descripción del símbolo
- Ordenar la estabilidad
- ECMAScript como superconjunto JSON
JSON.stringify
¡Feliz codificación JavaScript!