¡Hola! En este post hablare sobre las nuevas características que serán introducidas al lenguaje JavaScript. En especial sobre los nuevos tipos de datos “Record & Tuple” propuesto en el ECMAScript por Robin Ricard y Rick Button, en estos momentos se encuentran en la fase 2 (2021-01-01) sin embargo pronto cambiara. Esta feature incluye agregar dos tipos de valores primitivos al lenguaje:
- Records (similar a un objeto).
- Tuplas (similar a un array).
Syntaxis
La sintaxis es similar a los conocidos arreglos y objetos con una sutil diferencia, una almohadilla o signo de hash (#) al comienzo.
const person = #{
name: "Brian",
lastName: "Santeliz"
}
const lenguages = #["Javascript", "Python", "Haskell", "Rust"]
Características
De principio no parece nada especial, sin embargo tiene cosas muy interesantes. Te comentare alguna de las características de estos nuevos tipos de datos.
Inmutabilidad
Estos nuevos tipos de datos son inmutables, similar a lo que hace el método object.freeze()
con la diferencia de que una vez definido el Record o la Tuple no se podrán cambiar. Esto puede ser muy útil cuando se trabajan con librerías o frameworks que usan el principio de la inmutabilidad como React, además no tendremos que usar otras librerías de terceros como ImmutableJS para realizar estas operaciones.
const person = #{
name: "Brian",
lastName: "Santeliz"
}
person.age = "20" // Error
const lenguages = #["Javascript", "Python", "Haskell", "Rust"]
lenguages[0] = "Php" // Error
Estos tipos de datos pueden anidarse entre Records/Tuples y aplican las mismos principios de inmutabilidad.
const hero = #{
name: "Iron Man",
movies: #["Avengers", "Civil War", "Avengers: End Game"]
}
const lenguages = # ["Python", "Php", #{name:"JavaScript", creator:"Brendan Eich"}]
Igualdad
Una de las características que más me gustan y estoy seguro que otros desarrolladores también, es la capacidad de poder comparar records y tuples por su valor y no por su referencia. Veamos un ejemplo.
const obj = {name:"Hello"};
const obj2 = {name:"Hello"};
obj === obj2 //false
Aunque estoy comparando dos objetos que son iguales (a excepción del nombre) la comparación devuelve false, esto sucede porque Javascript compara sus referencias y no su valor, cada vez que creas un objeto este tendrá una referencia distinta. Una solución para esto seria, usando el método de JSON.stringify()
.
const obj = {name:"Hello"};
const obj2 = {name:"Hello"};
JSON.stringify(obj) === JSON.stringify(obj2)
//true
Sin embargo este método tiene algunos problemas importantes y no es una forma segura y rápida de resolverlo. La buena noticia es que con los Records & Tuples no es necesario ya que estos comparan por el valor y no por su referencia.
const obj = #{name:"Hello"};
const obj2 = #{name:"Hello"};
obj === obj2 //true
const colors = #["red","black","green", "blue"]
colors === #["red","black","green", "blue"]
//true
Genial! incluso con records/tuples anidados.
const lenguages = #[ "Php", #{name:"JavaScript", creator:"Brendan Eich"}]
lenguages === #["Php", #{name:"JavaScript", creator:"Brendan Eich"}]
//true
Como mencione anteriormente Los Records y Tuples son datos primitivos en JavaScript, esto se puede comprobar usando la sentencia de typeof
.
typeof #{a: 2, y: 3}
// "record"
typeof #[4,5,4]
//"tuple"
Compatibilidad con propiedades y métodos
Podemos utilizar los métodos que ya conocemos tanto para arreglo como para objetos. Destructuring, Spread & Rest operator, Higher order functions.
const hero = #{
name:"Iron Man ",
creator:"Marvel",
power:"1200"
}
//Destructuring & Rest operator.
const {name:newName, ...others} = hero;
console.log(others)
//{creator: "Marvel", power: "1200"}
const age = 34
const newHero = #{
...others, //syntax spread
age, //short notation
name:"Cap America"
};
const colors = #["yellow", "blue", "red"];
//filter method
const redColor = colors.filter((color)=>color === "red");
console.log(redColor)
//#["red"]
Trabajando con los métodos JSON
Algo que hay que tener en cuenta es que JSON.stringify()
trata los Records como objetos y las Tuples como array de manera recursiva. El metodo JSON.parseImmutable()
funciona como JSON.parse()
pero devuelve Records en lugar de objetos y Tuples en lugar de array nuevamente de manera recursiva.
const recordExample = JSON.parseImmutable('{"x":"Hello","y":["Banana","Apple"]}');
console.log(recordExample);
// #{x: "Hello", y: #["Banana", "Apple"]}
const objExample = JSON.stringify(recordExample);
console.log(objExample);
// "{x: "Hello", y: ["Banana", "Apple"]}"
Consideraciones
Estos nuevos tipos de datos tienen ciertas restricciones que debemos tener en cuenta, alguna de ella son:
- Records:
- Las key deben ser strings.
- Los valores deben ser primitivos.
- Tuples.
- Los elementos deben ser primitivos (no podemos incluir funciones por ejemplo).
Alguno de estos errores en código serian los siguientes:
//Error, no se pueden tener objetos.
const errorRecordObj = #{
obj: {
a: "i'm an object"
},
};
//Error, no se pueden tener funciones.
const errorRecordFunction = #{
example: () => alert("Hello World!")
};
//Ningún otro dato que no se un primitivo.
const errorRecordDate = #{
date: new Date(),
};
const errorRecordClass = #{
class: new Car(),
};
const errorTupleClass = #[new Car()];
const errorRecordSymbol = #{ [Symbol()]: #{} };
Conclusión
Para finalizar esto post quiero hablarte de los pros y contras que pude traer la nueva sintaxis, aunque en realidad son más los puntos positivos.
Ventajas: La nueva sintaxis es precisa. Es fácil de recordar y no tiene mucha diferencia con los objetos y arreglo, además de las ventajas de comparación por valores y la inmutabilidad.
Desventaja: Una desventaja que le encuentro podría ser que el uso de el carácter alfanumérico (#), puede tender a errores de sintaxis si no se usa la forma correcta. Esta sintaxis también es usada en campos privados de clases.
Eso es todo lo que quería compartirles, si tienes algún aporte o duda puedes comentarla. Puedes ir al Playground creado por Rick Button y ver los ejemplos que realice. Muchas gracias por leer ;).
Top comments (5)
Gracias por la noticia!
Aún así no veo que sea algo demasiado útil sinceramente 🤷🏻♂️
Pero lo dicho gracias por la info!!
no tiene mucha utilidad? cuando haces comparaciones entre conjuntos que tienen mutabilidad aunque tengan los mismos elementos y valores, siempre el resultado sera false, por el contrario cuando lo haces con variables inmutables como en este caso los Record y las Tuplas tendrias un resultado True, esto es algo que ni diversos métodos como el freeze te proporcionaban, por consiguiente el Perfomance que se obtendra en comparaciones debe ser extremadamente alto, como también esta el hecho de que podras hacer conversiones de datos que recibas y dicha conversion te mantendra inmutabilidad asegurada suponiendo un caso particular que sea una llamada para solo mostrar datos en un template, donde solo necesitas tener el Read de un Crud y no las demas funcionalidades o metodos, asi que solo lectura es mas que suficiente, entre muchas mas utilidades que se podran conseguir al tenerlo oficialmente en la nueva version de Ecmascript de forma nativa, asi que es cuestion de tener un contexto mas amplio de las cosas
Hey muchas gracias. Si es cierto que de momento no tiene mucha utilidad sin embargo en un futuro si que la tendrá, en principio porque se están añadiendo datos inmutables que son primitivos al lenguaje. Algo que le hacia falta, un ejemplo podría ser en React cuando creas un componente y le defines una record como estado, luego pasas este record como prop a otro componente y el estado de ese prop no se podrá mutar, algo que se busca en esta librería. Así como este hay otros problemas que se pueden solucionar usándolos. Saludos!
Genial bro!
Gracias Bro!