使原始数据类型在JavaScript中只读/不配置

时间:2011-06-18 12:57:52

标签: javascript object properties readonly

有没有人有任何将单个对象道具设为readOnly / non-configurable的示例实现?我的意思是原始数据类型。尝试过使用ES5 Object API,但是碰到了一堵砖墙。

我无法显示代码,因为它仍处于“混乱”阶段,但基本上我正在迭代一个外部对象,它本身拥有数字对象。这些对象各自拥有各种原始数据类型。我已经将外部对象设为readOnly,non-config等,但无法弄清楚如何为各个道具,最里面的道具做同样的事情。

因此,如果outer.inner.prop === "Hello",我想将该值readOnly

谢谢!

更新

我只想到了这一点,它全部在我用来迭代道具的for循环中。现在我实际上已经获得了道具的数据描述符,甚至是原始道具。 :)谢谢大家!

4 个答案:

答案 0 :(得分:2)

您必须遍历内部对象,因为无法使用标准ES5方法对对象进行深度冻结。

function deepFreeze(obj) {
    Object.keys(obj).forEach(function (key) {
        if (typeof obj[key] == 'object')
            deepFreeze(obj[key]);
    });
    Object.freeze(obj);
}

修改 如果您不想defineProperty

,也适用于freeze
function deepWriteProtect(obj) {
    Object.keys(obj).forEach(function (key) {
        if (typeof obj[key] == 'object')
            deepWriteProtect(obj[key]);
        Object.defineProperty(obj, key, { writable: false });
    });
}

答案 1 :(得分:1)

我并非100%确定我正确理解了您的问题,但从我收集的内容中您要求私有变量。如果是这样,可以使用闭包轻松实现。

function myClass(){
    var mySecretProperty = 10;
    this.getMySecretProperty = function(){
         return mySecretProperty;
    }
    this.changeMySecretProperty = function(s){
         // whatever logic you need for a setter method
         mySecretProperty = s;
    }
}

var myObj = new MyClass();
myObj.changeMySecretProperty(120);
myObj.getMySecretProperty(); // will return 120
myObj.mySecretProperty // will return undefined

答案 2 :(得分:1)

以下(ES5)示例会有帮助吗?它创建了一个空构造函数,其中包含属性a的getter(并且没有setter,因此事实上a是只读的):

var Obj = function(){};
Obj.prototype = {
    get a() {return 5;}
}
var x = new Obj;
alert(x.a); //=> 5
x.a = 6; //=> TypeError: setting a property that has only a getter

你不能使用ES5

var Obj = function(){
  var a = 5;
  if (!Obj.prototype.getA) {
     Obj.prototype.getA = {
         toString: function() {
            return a;
         }
     };
  }
}

var y = new Obj;
alert(y.getA); //=> 5

但这不是100%故障安全:Obj.prototype.getA可以被覆盖。

答案 3 :(得分:1)

Here是一个jsfiddle,展示了如何使用ES5 getter / setter定义来使对象的属性成为只能被提取的东西。代码如下所示:

var object = {
    get x() {
        return 17;
    }, set x() {
        alert("You cannot set x!");
    }
};

当然,getter可以从任何地方获取属性(“x”)的值,比如构造函数或其他东西的闭包。关键是setter不会更改值,因此尝试更改它:

object.x = 100;

不会有任何影响。