Configurar propiedades de clases en javascript

De ChuWiki
Saltar a: navegación, buscar

En javascript podemos definir una clase con propiedades o atributos de esta forma

var a = {x:11, y:22}

Estas propiedades son por defecto visibles y modificables, pero tenemos formas de configurar todo esto. Vamos a ver algunas posibilidades


defineProperty()

La clase Object de javascript tiene un método defineProperty() que nos permite definir propiedades en otras clases, de forma similar a como definirmo x e y en el ejemplo anterior. La ventaja de defineProperty() es que nos permite configurar esa propiedad con cuatro posibles características:

  • value es el valor que queremos que tenga, 11 y 22 en el ejemplo anterior
  • writable puede ser true o false y nos indica si esa propiedad admite que se cambie su valor o no.
  • enumearable puede ser true o false y nos indica si esa propiedad aparecerá en un bucle que hagamos recorriendo las propiedades de un objeto (ver más abajo).
  • configurable puede ser true o false e indica si esa propiedad puede ser reconfigurada o no.

Object.defineProperty() admite tres parámetros, el objeto al que queremos añadir/modificar la propiedad, el nombre de la propiedad y las opciones que queremos ponerle/modificarle. Devuelve el objeto modificado, así que serían posibles estas llamadas

// Si estamos creando un objeto nuevo
var a = Object.defineProperty({}, "x", { value:11, writable:true, enumerable:true, configurable:true});

// Si el objeto ya está definido
var a = {};
Object.defineProperty(a, "x", { value:11, writable:true, enumerable:true, configurable:true});

Un detalle a tener en cuenta. Si la propiedad es nueva, los valores por defecto para cada opción son false, por lo que si no rellenamos alguna, será false. En el siguiente caso por ejemplo

var a = Object.defineProperty({}, "x", {value:11});

la propiedad x no será writable, no será enumerable y no será configurable. Si la propiedad ya existe, entonces las opcoines que no pongamos no se modificarán y permanecerán como ya las tuviera la propiedad. Por ejemplo, si hacemos

var a = {x:11};   // es writable, enumerable y configurable por defecto al definirla asi
Object.setProperty(a, "x", {writable:false});  // Ahora es no writable, pero sigue siendo enumerable y configurable.

value

Si tenemos una objeto a, podemos definirle una propiedad y darle un valor de esta forma

var a = {};
Object.defineProperty (a, "x", {value:11});
// ahora a.x vale 11

Como comentábamos antes, al no poner el resto de opciones, esta a.x es no writable, no enumerable y no configurable.


writable

Si definimos así la propiedad

var a = Object.defineProperty({}, "x", {value:11, writable:false});

La propiedad vale 11 y no se puede modificar. Si hacemos

a.x=22;

no dará error, pero a.x seguirá valiendo 11. Un detalle a tener en cuenta es que si la propiedad no es writable, pero sí es configurable, podemos cambiar su valor a través de defineProperty. Por ejemplo

var a = Object.defineProperty({}, "x", {value:11, writable:false, configurable:true});
Object.defineProperty(a, "x", {value:22});  // Esto cambia el valor aunque sea no writable. Ahora x.a vale 22


enumerable

Si definimos un objeto así

var a = {x:11, y:22};

podemos hacer un bucle para recorrer cada una de sus propiedades de esta forma

for ( propiedad in a ) {
   console.log (propiedad);  // Va escribiendo cada propiedad
}
// Esto saca en pantalla
// x
// y

Pues bien, si hacemos que una propiedad sea no enumerable, no aparecera al recorrerla con este tipo de bucle

Object.defineProperty (a, "x", {enumerable:false});
for ( propiedad in a ) {
   console.log (propiedad);  // Va escribiendo cada propiedad
}
// Esto saca en pantalla solo la y
// y


configurable

Esta es la opción que nos indica si vamos a poder usar el defineProperty() más adelante otra vez para cambiar algo o no. Si no es configurable, no podemos volver a cambiar nada, excepto hacer cambiar writable true por false. Por ejemplo, si hacemos

var a = {x:1};
Object.defineProperty(a, "x", {configurable:false});

a partir de aquí obtenemos error con cualquiera de las siguientes

Object.defineProperty(a, "x", {configurable:true});
Object.defineProperty(a, "x", {writable:true});
Object.defineProperty(a, "x", {value:2});
// Dan error "TypeError: Cannot redefine property: x"