Comprender cómo funcionan los métodos estáticos del superprototipo Object es fundamental para trabajar con objetos en JavaScript de forma profesional. Más allá de acceder a propiedades con el punto o los corchetes, existen herramientas que permiten listar, inspeccionar y definir propiedades con un nivel de control que pocos desarrolladores aprovechan desde el inicio.
¿Cómo listar las propiedades de un objeto con Object.keys y Object.getOwnPropertyNames?
Para este ejercicio se parte de un objeto llamado juan con atributos como name, edad, approvedCourses (un array de cursos aprobados) y un método addCourse que utiliza this.approvedCourses.push(newCourse) para agregar nuevos cursos a la lista [01:00].
El primer método estático es Object.keys, que recibe un objeto como argumento y devuelve un array con los nombres de todas sus propiedades, sin importar si son atributos o métodos [02:42].
javascript
Object.keys(juan);
// ["name", "edad", "approvedCourses", "addCourse"]
El segundo es Object.getOwnPropertyNames, que en apariencia hace lo mismo: retorna un array con cada propiedad del objeto [03:10]. La diferencia entre ambos se vuelve relevante cuando existen propiedades no enumerables, algo que se explora más adelante.
¿Qué devuelve Object.entries y por qué cambia el contexto de this?
Object.entries va un paso más allá. Retorna un array de arrays, donde cada sub-array contiene dos elementos: la llave y el valor de cada propiedad [03:25].
javascript
Object.entries(juan);
// [["name", "Juanito"], ["edad", 18], ["approvedCourses", [...]], ["addCourse", ƒ]]
Es posible acceder a posiciones específicas de este resultado. Por ejemplo, Object.entries(juan)[3] muestra el array ["addCourse", ƒ] y con [3][1] se obtiene la función en sí [04:10].
Sin embargo, ejecutar un método desde Object.entries genera un problema con this. Al intentar Object.entries(juan)[3][1]("curso 3"), se obtiene un TypeError: Cannot read property push of undefined [05:05]. La razón es que this ya no apunta al objeto juan, sino al array donde está almacenada la función. Este comportamiento está directamente relacionado con los conceptos de closures y scope:
- Cuando se llama
juan.addCourse("curso 2"), this referencia correctamente al objeto juan [05:55].
- Cuando se ejecuta la misma función a través de
Object.entries, el contexto cambia: this pasa a ser el array interno, no el objeto original [07:00].
Este detalle es crucial al trabajar con funciones extraídas de objetos mediante Object.entries.
¿Qué son writable, enumerable y configurable en Object.getOwnPropertyDescriptors?
El método más revelador es Object.getOwnPropertyDescriptors [08:00]. En lugar de un array, devuelve un objeto donde cada propiedad contiene un descriptor con estos atributos:
- value: el valor almacenado en la propiedad.
- writable: indica si el valor puede ser modificado.
- enumerable: determina si la propiedad aparece al iterar el objeto.
- configurable: controla si la propiedad puede ser eliminada o si sus descriptores pueden cambiar.
javascript
Object.getOwnPropertyDescriptors(juan);
// { name: { value: "Juanito", writable: true, enumerable: true, configurable: true }, ... }
Estos tres atributos por defecto están en true cuando se crean propiedades de forma convencional. Revelan que los objetos en JavaScript no son simples pares de llave-valor, sino que cada propiedad lleva consigo metadatos que definen su comportamiento.
¿Cómo crear propiedades con Object.defineProperty?
Para manipular estos descriptores existe Object.defineProperty, que recibe tres argumentos [09:30]:
- El objeto destino.
- El nombre de la nueva propiedad como string.
- Un objeto con
value, writable, enumerable y configurable.
javascript
Object.defineProperty(juan, "pruebaNasa", {
value: "extraterrestres",
writable: true,
enumerable: true,
configurable: true
});
A diferencia de asignar propiedades con el punto o los corchetes, este método permite controlar exactamente el comportamiento de cada propiedad desde su creación, lo que abre la puerta al encapsulamiento en objetos de JavaScript.
Experimenta cambiando writable, enumerable o configurable a false y observa cómo se restringe el acceso y la modificación de tus propiedades. ¿Ya probaste qué sucede cuando enumerable es false y ejecutas Object.keys? Comparte tu resultado en los comentarios.