2009-08-24 11 views
4

Est-il possible de rendre une propriété d'objet javascript en lecture seule? Je veux définir une propriété qui ne peut pas être modifiée ...propriété en lecture seule

Répondre

7

C'est possible, mais cher. Vous pouvez le faire en ayant une variable membre vraiment privé et fournir une fonction accesseur:

var NiftyThing = function() { 
    var trulyPrivateVariable; 

    trulyPrivateVariable = 5; // For instance 
    this.accessorFunction = function() { 
     return trulyPrivateVariable; 
    } 
}; 

Cela fonctionne parce que la fonction accesseur est une fermeture sur le var. Le coût est que chaque instance a sa propre copie de la fonction d'accesseur.

EDIT: Utilisation:

var n = new NiftyThing(); 
alert(n.trulyPrivateVariable); 
// Alerts "undefined" 
alert(n.accessorFunction()); 
// Alerts "5" 

Voir Private Member Variables in JavaScript pour plus.

+3

bien, notez que accessorFunction peut être remplacé par un utilisateur déterminé. Bien que cela n'affecte pas la valeur de privatePrivateVariable, cela affecte tout ce qui appelle accessorFunction. – cobbal

0

Je suis d'accord avec la réponse, et tient à souligner que certains frameworks JavaScript comme bob.js soutien de tels mécanismes intégrés:

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. 

Cependant, si vous avez des besoins particuliers en matière de propriété, tels que accesseur get spécifique besoins de mise en œuvre, puis mieux définir une fonction qui obtient la valeur que vous en avez besoin.

- Tengiz

0

Vous pouvez mettre en œuvre quelque chose comme ça, faisant usage de Object.defineProperty():

function blockProperties(object, properties) { 
    "use strict"; 
    // If not properties passed, then use the already defined ones: 
    if (typeof properties === "undefined") { 
     properties = object; 
    } 
    // Loop trough the properties 
    for (var property in properties) { 
     if (properties.hasOwnProperty(property)) { 
      // Make property read-only 
      Object.defineProperty(object, property, { 
       value: properties[property], 
       writable: false, 
       configurable: false, 
       enumerable: false 
      }); 
     } 
    } 
    return object; 
} 

var someObject = {}; 

blockProperties(someObject, { 
    propertie1: "someValue", 
    propertie2: "someOtherValue" 
}); 

someObject.propertie1 = "this doesn't change anything"; 

console.log(someObject.propertie1); // Output: "someValue" 

// Because "window" is also an object, you can set an only-read global var: 
blockProperties(window, { 
    onlyReadVariable: "onlyReadValue" 
}); 
Questions connexes