2009-08-24 209 views
4

是否可以使JavaScript對象屬性爲只讀?我想設置一個不能修改的屬性...只讀屬性

回答

7

這是可能的,但昂貴。您可以通過具有真正的私有成員變量,然後提供存取功能做到這一點:

var NiftyThing = function() { 
    var trulyPrivateVariable; 

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

這工作,因爲訪問函數是一個封閉在變種。成本是每個實例都有自己的訪問函數副本。

編輯:用法:

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

更多見Private Member Variables in JavaScript

+3

雖然,注意accessorFunction可以通過確定的用戶覆蓋。雖然它不會影響真正的私人變量,但它會影響任何調用accessorFunction的東西。 – cobbal 2009-08-24 11:01:50

0

我同意了答案,並想指出一些JavaScript框架,如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. 

但是,如果您有任何關於財產的特殊需求,如特定get訪問實現需求,然後更好地定義一個函數,根據需要獲取價值。

- 吉茲

0

您可以實現這樣的事情,利用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" 
});