En regardant la mozilla documentation , en regardant l’exemple d’expression régulière (intitulé "Création d’un tableau en utilisant le résultat d’une correspondance"), nous avons des instructions du type:
input: propriété en lecture seule qui reflète la chaîne d'origine par rapport à laquelle l'expression régulière a été mise en correspondance.
index: propriété en lecture seule qui correspond à l'index de base zéro de la correspondance dans la chaîne.
etc ... est-il possible de créer votre propre objet en JavaScript qui aura des propriétés en lecture seule, ou s'agit-il d'un privilège réservé aux types intégrés implémentés par des navigateurs particuliers?
Edit: Depuis que cette réponse a été écrite, une nouvelle méthode plus efficace utilisant Object.defineProperty
a été normalisée dans EcmaScript 5, avec une prise en charge dans les nouveaux navigateurs. Voir Réponse de Aidamina . Si vous devez prendre en charge les "anciens" navigateurs, vous pouvez utiliser l'une des méthodes de cette réponse comme solution de secours.
Dans Firefox, Opera 9.5+, Safari 3+, Chrome et IE (testé avec v11), vous pouvez définir les propriétés de lecture et de définition. Si vous définissez uniquement un getter, cela crée effectivement une propriété en lecture seule. Vous pouvez les définir dans un littéral d'objet ou en appelant une méthode sur un objet.
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 vous avez déjà un objet, vous pouvez appeler __defineGetter__
et __defineSetter__
:
var myObject = {};
myObject.__defineGetter__("readOnlyProperty", function() { return 42; });
Bien sûr, cela n’est pas vraiment utile sur le Web car cela ne fonctionne pas dans Internet Explorer.
Vous pouvez en savoir plus à ce sujet sur le blog de John Resig ou le Mozilla Developer Center .
Avec tout interpréteur javascript implémentant ECMAScript 5 , vous pouvez utiliser Object.defineProperty pour définir les propriétés en lecture seule. En mode lâche, l'interprète ignore une écriture sur la propriété, en mode strict, il lève une exception.
Exemple de ejohn.org :
var obj = {};
Object.defineProperty( obj, "<yourPropertyNameHere>", {
value: "<yourPropertyValueHere>",
writable: false,
enumerable: true,
configurable: true
});
Il est possible d'avoir des propriétés en lecture seule en JavaScript, disponibles via les méthodes getter. Cela s'appelle généralement le modèle 'Module'.
Le blog de YUI en a une bonne description: http://yuiblog.com/blog/2007/06/12/module-pattern/
Extrait du message:
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
En tant que propriété ou variable en lecture seule, il l’est.
Comme aidamina a dit , et voici un code court pour tester, soit dit en passant, très utile maintenant que JQuery prétend déprécier la propriété 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>
Vous avez donc une propriété ou une variable en lecture seule testée.
Oui, nous pouvons avoir une propriété en lecture seule pour un objet en JavaScript. Il peut être réalisé avec une variable privée et la méthode object.defineProperty()
,
Voir l'exemple suivant qui illustre que l'objet possède une propriété en lecture seule,
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
Voici un lien vers la page de Douglas Crockford sur "Membres privés en Javascript" .... il me semble que celles-ci ne seraient lues que si seules les méthodes getter sont fournies, et pas de setters:
Vous verrez que j'ai défini un setter et un getter pour la couleur afin de pouvoir la modifier. En revanche, la marque devient en lecture seule une fois que l'objet est défini. Je crois que c'est la fonctionnalité que vous recherchiez.
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
Ce qui précède a été testé sur la version 41.0.2272.76 Ubuntu 14.04 de Chromium et a donné la sortie suivante:
Porche Red BMW White Mercedes Black Green Green function () { return color; } Black
bob.js framework fournit un moyen de déclarer des propriétés en lecture seule. Sous le capot, il déclare un champ privé et expose les fonctions de lecture/définition pour celui-ci. bob.js offre plusieurs façons de faire la même chose, en fonction de la commodité et des objectifs spécifiques. Voici une approche qui utilise l'instance orientée objet de la Property
(d'autres approches permettent de définir des setters/getters sur l'objet lui-même):
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
À la fin, p.name.set_value
n'est pas défini car il s'agit d'une propriété en lecture seule.