在JavaScript中定义只读属性

Šim*_*das 51 javascript

给定一个对象obj,我想定义一个只读属性'prop'并将其值设置为val.这是正确的方法吗?

Object.defineProperty( obj, 'prop', {
    get: function () {
        return val;
    }
});
Run Code Online (Sandbox Code Playgroud)

结果应该是(for val = 'test'):

obj.prop; // 'test'
obj.prop = 'changed';
obj.prop; // still 'test' since it's read-only
Run Code Online (Sandbox Code Playgroud)

这个方法 很有用:http://jsfiddle.net/GHMjN/
我只是不确定这是否是最简单/最顺利/最合适的方式...

Tim*_*own 92

您可以使用writable属性描述符的属性,这可以防止需要get访问者:

var obj = {};
Object.defineProperty(obj, "prop", {
    value: "test",
    writable: false
});
Run Code Online (Sandbox Code Playgroud)

如评论中所述,该writable选项默认为false在这种情况下您可以省略它:

Object.defineProperty(obj, "prop", {
    value: "test"
});
Run Code Online (Sandbox Code Playgroud)

这是ECMAScript 5,因此无法在旧版浏览器中使用.

  • 请注意,最终对象/数组的**子属性**仍然可以修改**。在这种情况下,只有“prop”键无法重新分配。 (3认同)

Fir*_*ind 6

在新的浏览器或node.js 中,可以使用Proxy创建只读对象。

var obj = {
    prop: 'test'
}

obj = new Proxy(obj ,{
    setProperty: function(target, key, value){
        if(target.hasOwnProperty(key))
            return target[key];
        return target[key] = value;
    },
    get: function(target, key){
        return target[key];
    },
    set: function(target, key, value){
        return this.setProperty(target, key, value);
    },
    defineProperty: function (target, key, desc) {
        return this.setProperty(target, key, desc.value);
    },
    deleteProperty: function(target, key) {
        return false;
    }
});
Run Code Online (Sandbox Code Playgroud)

您仍然可以为该对象分配新属性,并且它们也是只读的。

例子

obj.prop
// > 'test'

obj.prop = 'changed';
obj.prop
// > 'test'

// New value
obj.myValue = 'foo';
obj.myValue = 'bar';

obj.myValue
// > 'foo'
Run Code Online (Sandbox Code Playgroud)