validacion - ¿Se pueden implementar las propiedades de solo lectura en JavaScript puro?
validar formulario javascript html5 (8)
Aquí hay un enlace a la página de Douglas Crockford sobre "Miembros privados en Javascript" ... me parece que estos solo se leerán si se proporcionan solo métodos getter, y no establecedores:
Mirando la documentación de mozilla , mirando el ejemplo de expresión regular (encabezado "Creando una matriz usando el resultado de una coincidencia"), tenemos declaraciones como:
entrada: una propiedad de solo lectura que refleja la cadena original contra la cual se combinó la expresión regular.
índice: propiedad de solo lectura que es el índice basado en cero de la coincidencia en la cadena.
etc ... ¿es posible crear su propio objeto en JavaScript que tendrá propiedades de solo lectura, o es un privilegio reservado a los tipos incorporados implementados por navegadores específicos?
Como propiedad de solo lectura o variable aquí está.
Como dijo Aidamina , y aquí hay un código corto para probar, por cierto, muy útil ahora que JQuery pretende depreciar la propiedad del selector.
<script>
Object.defineProperties(window, {
"selector": { value: ''window'', writable: false }
});
alert (window.selector); // outputs window
selector =''ddd''; // testing because it belong to the global object
alert (window.selector); // outputs window
alert (selector); // outputs window
window.selector=''abc'';
alert (window.selector); // outputs window
alert (selector); // outputs window
</script>
Entonces, tienes una propiedad de solo lectura o una variable probada.
Con cualquier intérprete de JavaScript que implemente ECMAScript 5 , puede usar Object.defineProperty para definir propiedades de solo lectura. En modo suelto, el intérprete ignorará una escritura en la propiedad, en modo estricto arrojará una excepción.
Ejemplo de ejohn.org :
var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
value: "<yourPropertyValueHere>",
writable: false,
enumerable: true,
configurable: true
});
Es posible tener propiedades de solo lectura en JavaScript que están disponibles a través de métodos getter. Esto generalmente se llama el patrón ''Módulo''.
El blog de YUI tiene una buena descripción de él: http://yuiblog.com/blog/2007/06/12/module-pattern/
Fragmento de la publicación:
YAHOO.myProject.myModule = function () {
//"private" variables:
var myPrivateVar = "I can be accessed only from within YAHOO.myProject.myModule.";
//"private" method:
var myPrivateMethod = function () {
YAHOO.log("I can be accessed only from within YAHOO.myProject.myModule");
}
return {
myPublicProperty: "I''m accessible as YAHOO.myProject.myModule.myPublicProperty."
myPublicMethod: function () {
YAHOO.log("I''m accessible as YAHOO.myProject.myModule.myPublicMethod.");
//Within myProject, I can access "private" vars and methods:
YAHOO.log(myPrivateVar);
YAHOO.log(myPrivateMethod());
//The native scope of myPublicMethod is myProject; we can
//access public members using "this":
YAHOO.log(this.myPublicProperty);
}
};
}(); // the parens here cause the anonymous function to execute and return
Sí, podemos haber leído solo la propiedad de un objeto en JavaScript. Se puede lograr con la variable privada y el método object.defineProperty()
,
Vea el siguiente ejemplo que ilustra un objeto que tiene solo propiedad de lectura,
function Employee(name,age){
var _name = name;
var _age = age;
Object.defineProperty(this,''name'',{
get:function(){
return _name;
}
})
}
var emp = new Employee(''safeer'',25);
console.log(emp.name); //return ''safeer''
emp.name=''abc'';
console.log(emp.name); //again return ''safeer'', since name is read-only property
Verás que he definido un setter y getter para el color para que pueda ser modificado. La marca, por otro lado, se convierte en de solo lectura una vez que se define el objeto. Creo que esta es la funcionalidad que estabas buscando.
function Car(brand, color) {
brand = brand || ''Porche''; // Private variable - Not accessible directly and cannot be frozen
color = color || ''Red''; // Private variable - Not accessible directly and cannot be frozen
this.color = function() { return color; }; // Getter for color
this.setColor = function(x) { color = x; }; // Setter for color
this.brand = function() { return brand; }; // Getter for brand
Object.freeze(this); // Makes your object''s public methods and properties read-only
}
function w(str) {
/*************************/
/*choose a logging method*/
/*************************/
console.log(str);
// document.write(str + "<br>");
}
var myCar = new Car;
var myCar2 = new Car(''BMW'',''White'');
var myCar3 = new Car(''Mercedes'', ''Black'');
w(myCar.brand()); // returns Porche
w(myCar.color()); // returns Red
w(myCar2.brand()); // returns BMW
w(myCar2.color()); // returns White
w(myCar3.brand()); // returns Mercedes
w(myCar3.color()); // returns Black
// This works even when the Object is frozen
myCar.setColor(''Green'');
w(myCar.color()); // returns Green
// This will have no effect
myCar.color = ''Purple'';
w(myCar.color()); // returns Green
w(myCar.color); // returns the method
// This following will not work as the object is frozen
myCar.color = function (x) {
alert(x);
};
myCar.setColor(''Black'');
w(
myCar.color(
''This will not work. Object is frozen! The method has not been updated''
)
); // returns Black since the method is unchanged
Lo anterior se ha probado en Chromium versión 41.0.2272.76 Ubuntu 14.04 y arrojó el siguiente resultado:
Porche Red BMW White Mercedes Black Green Green function () { return color; } Black
El marco bob.js proporciona una forma de declarar propiedades de solo lectura. Debajo del capó, declara un campo privado y expone las funciones getter / setter para él. bob.js proporciona múltiples formas de hacer lo mismo, según la conveniencia y los objetivos específicos. Aquí hay un enfoque que usa la instancia orientada a objetos de la Property
(otros enfoques permiten definir setters / getters en el objeto mismo):
var Person = function(name, age) {
this.name = new bob.prop.Property(name, true);
var setName = this.name.get_setter();
this.age = new bob.prop.Property(age, true);
var setAge = this.age.get_setter();
this.parent = new bob.prop.Property(null, false, true);
};
var p = new Person(''Bob'', 20);
p.parent.set_value(new Person(''Martin'', 50));
console.log(''name: '' + p.name.get_value());
console.log(''age: '' + p.age.get_value());
console.log(''parent: '' + (p.parent.get_value ? p.parent.get_value().name.get_value() : ''N/A''));
// Output:
// name: Bob
// age: 20
// parent: N/A
Al final, p.name.set_value
no está definido porque es una propiedad de solo lectura.
Editar: Desde que se escribió esta respuesta, se ha estandarizado una nueva y mejor forma de usar Object.defineProperty
en EcmaScript 5, con soporte en los navegadores más nuevos. Ver la respuesta de Aidamina . Si necesita admitir navegadores "anteriores", podría usar uno de los métodos de esta respuesta como alternativa.
En Firefox, Opera 9.5+ y Safari 3+, Chrome e IE (probado con v11) puede definir las propiedades getter y setter. Si solo defines un getter, efectivamente crea una propiedad de solo lectura. Puede definirlos en un literal de objeto o llamando a un método en un objeto.
var myObject = {
get readOnlyProperty() { return 42; }
};
alert(myObject.readOnlyProperty); // 42
myObject.readOnlyProperty = 5; // Assignment is allowed, but doesn''t do anything
alert(myObject.readOnlyProperty); // 42
Si ya tiene un objeto, puede llamar a __defineGetter__
y __defineSetter__
:
var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });
Por supuesto, esto no es realmente útil en la web porque no funciona en Internet Explorer.
Puede leer más sobre esto en el blog de John Resig o en el Mozilla Developer Center .