【问题标题】:read-only property只读属性
【发布时间】:2010-11-22 05:50:27
【问题描述】:

是否可以将 javascript 对象属性设为只读?我要设置一个不能修改的属性...

【问题讨论】:

    标签: javascript variables object


    【解决方案1】:

    这是可能的,但价格昂贵。你可以通过拥有一个真正私有的成员变量然后提供一个访问函数来做到这一点:

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

    之所以有效,是因为访问器函数是对 var 的闭包。代价是每个实例都有自己的访问器函数副本。

    编辑:用法:

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

    请参阅Private Member Variables in JavaScript 了解更多信息。

    【讨论】:

    • 尽管如此,请注意 accessorFunction 可以被确定的用户覆盖。虽然它不会影响真正的PrivateVariable,但它会影响任何调用accessorFunction的东西。
    【解决方案2】:

    您可以使用 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"
    });
    

    【讨论】:

      【解决方案3】:

      我同意这个答案,并想指出一些 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 访问器实现需求,那么最好定义一个函数来获取您需要的值。

      - 腾吉斯

      【讨论】:

        猜你喜欢
        • 2014-08-22
        • 2015-02-01
        • 2011-01-28
        • 2015-05-17
        • 2011-11-08
        • 2018-06-04
        • 2015-09-03
        • 1970-01-01
        相关资源
        最近更新 更多