2011-10-13 44 views
35

給定一個對象obj,我想定義一個只讀屬性'prop'並將其值設置爲val。這是做這件事的正確方法嗎?在JavaScript中定義只讀屬性

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

結果應該是(爲val = 'test'):

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

此方法BTW:http://jsfiddle.net/GHMjN/
我只是不能確定這是否是最容易/光滑/最適當的方式做到這一點...

+0

可能的重複:http://stackoverflow.com/questions/366047/can-read-only-properties-be-implemented-in-pure-javascript(如果你不想支持舊瀏覽器,你的方法是最好的) –

回答

64

您可改爲使用屬性描述符的writable屬性,該屬性可防止需要get訪問器:

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

這是ECMAScript 5,所以在舊版瀏覽器中不起作用。

+0

我不確定我的代碼和代碼是否會在「外部」產生完全相同的結果,但是您的方法無疑是更正確的方法。 –

0

由於舊的瀏覽器(向後兼容性),我必須爲屬性提供訪問函數。我做了它的一部分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. 

我希望它有幫助。

+0

等待,'.namedProp(obj,'foo')',在對象本身上創建'.get_foo()',/'.set_foo()'?這不是非常有效。我想我會用一個包裝,例如'X(OBJ).SET( '富')'/'X(OBJ)獲得( '富')'。 –

+0

澄清:我認爲我們正在談論兩件不同的事情。你可能想保持真實的對象不變,同時有一個包裝它;但我建議改變真實的對象並且有代表屬性的函數。因爲爲了向後兼容,舊式JavaScript屬性可能被視爲字段。因此,你需要爲它添加訪問器(函數)(另外我建議從實際對象中刪除傳統的JS屬性,從而完全控制屬性)。至於封裝,這也不錯,但與我的方法不同。 – Tengiz