Propiedades dinámicas con Object.defineProperty (I)

Una de las novedades de JavaScript pre-ECMAScript 6 fue el paquete de métodos que se le agregó a la función Object. Antes de esto, un objeto en JavaScript era un conjunto de propiedades y valores bastante básico. Una de los métodos de este paquete es defineProperty.

Object.defineProperty permite definir propiedades dinámicas en un objeto. Una propiedad dinámica puede devolver un valor diferente según ciertas condiciones (condiciones que son definidas en algún punto del código).

Este método toma 3 parámetros: El objeto al cual se agregará la propiedad, el nombre de la propiedad y un objeto con la configuración de la nueva propiedad.

La configuración de la nueva propiedad puede ser de dos tipos: de datos o de acceso.

Cuando la configuración es de datos, acepta dos propiedades: value y writable. value guarda el valor inicial que tendrá la nueva propiedad, mientras que writable es un booleano que va a indicar si la propiedad puede ser sobreescrita.

Por otro lado, si la configuración es de acceso, acepta dos funciones: get y set. Estas funciones serán llamadas internamente al momento de acceder o escribir el valor de la propiedad.

Sea cualquiera de los dos tipos de configuración, también aceptan dos propiedades más: configurable y enumerable, ambos booleanos. configurable define si la propiedad puede ser o no eliminada del objeto, mientras que enumerable define si la propiedad aparecerá o no en el array que devuelve Object.keys, o al utilizar for..in.

Utilizar la configuración de datos no es muy útil, a menos que queramos definir un valor por default para una propiedad, pero la configuración de acceso ofrece un mundo de posibilidades para los objetos en JavaScript.

Por ejemplo, podemos tener un objeto person, el cual tiene nombre (firstName) y apellido (lastName), y crearle una propiedad dinámica llamada fullName, que nos dará el nombre completo.

Esta propiedad será de solo lectura, ya que no hemos definido la función set. Sin embargo, si cambiamos los valores de firstName y lastName, automáticamente el valor de fullName cambiará.