2011-10-13 9 views
35

Dado un objeto obj, me gustaría definir una propiedad de solo lectura 'prop' y establecer su valor en val. ¿Es esta la manera correcta de hacer eso?Definición de propiedades de solo lectura en JavaScript

Object.defineProperty(obj, 'prop', { 
    get: function() { 
     return val; 
    } 
}); 

El resultado debería ser (por val = 'test'):

obj.prop; // 'test' 
obj.prop = 'changed'; 
obj.prop; // still 'test' since it's read-only 

Este método funciona por cierto: http://jsfiddle.net/GHMjN/
Sólo soy seguro si esta es la forma más fácil/más suave/más adecuada para hacerlo ...

+0

Posible duplicado: http://stackoverflow.com/questions/366047/can-read-only-properties-be-implemented-in-pure-javascript (Si no desea admitir navegadores antiguos, su método es el mejor) –

Respuesta

64

En su lugar, podría utilizar la propiedad writable del descriptor de la propiedad, lo que evita la necesidad de un acceso get:

var obj = {}; 
Object.defineProperty(obj, "prop", { 
    value: "test", 
    writable: false 
}); 

Esto es ECMAScript 5 por lo que no funcionará en los navegadores más antiguos.

+0

No estoy seguro si mi código y tu código producen exactamente el mismo resultado "en el exterior", pero su método es sin duda la forma más adecuada de hacerlo. –

0

Debido a los navegadores antiguos (compatibilidad con versiones anteriores) tuve que buscar funciones de acceso para las propiedades. Lo hice parte de bob.js:

var obj = { }; 
//declare read-only property. 
bob.prop.namedProp(obj, 'name', 'Bob', true); 
//declare read-write property. 
bob.prop.namedProp(obj, 'age', 1); 

//get values of properties. 
console.log(bob.string.formatString('{0} is {1} years old.', obj.get_name(), obj.get_age())); 
//set value of read-write property. 
obj.set_age(2); 
console.log(bob.string.formatString('Now {0} is {1} years old.', obj.get_name(), obj.get_age())); 

//cannot set read-only property of obj. Next line would throw an error. 
// obj.set_name('Rob'); 

//Output: 
//======== 
// Bob is 1 years old. 
// Now Bob is 2 years old. 

espero que ayude.

+0

Espera, '.namedProp (obj, 'foo')', crea '.get_foo()',/'.set_foo()' en el objeto mismo? Eso no es muy eficiente. Creo que iría con un envoltorio, p. 'X (obj) .set ('foo')'/'X (obj) .get ('foo')'. –

+0

Para aclarar: creo que estamos hablando de dos cosas diferentes. Posiblemente quiera mantener el objeto real sin cambios mientras tiene un envoltorio alrededor; pero sugerí cambiar el objeto real y tener funciones que representan propiedades. Debido a la compatibilidad con versiones anteriores, las propiedades de JavaScript antiguas pueden tratarse como campos. Por lo tanto, necesitaría tener accesores (funciones) para ello (además, sugeriría eliminar las propiedades tradicionales de JS del objeto real, y así tener un control completo sobre las propiedades). Como sobre los envoltorios, eso tampoco es malo, pero difiere de mi enfoque. – Tengiz

Cuestiones relacionadas