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

发布于 2024-11-16 05:17:04 字数 400 浏览 3 评论 0原文

有谁有使单个对象道具只读/不可配置的示例实现吗?我的意思是原始数据类型。曾尝试使用 ES5 Object API,但遇到了困难。

我无法显示代码,因为它仍然处于“混乱”阶段,但基本上我正在迭代一个外部对象,该对象本身包含许多对象。这些对象各自保存各种原始数据类型。我已将外部对象设置为只读、非配置等,但不知道如何对单个道具(最里面的道具)执行同样的操作。

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

谢谢!

更新

我刚刚发现了这一点,这一切都在我用来迭代 props 的 for 循环中。现在我实际上已经获得了道具的数据描述符,甚至是原始的数据描述符。 :) 谢谢大家!

Does anyone have any example implementation of making individual object props readOnly/non-configurable? I mean primitive data types. Have tried using ES5 Object API, but hitting a brick wall.

I can't show code, because it's still at that "messy" phase, but basically I'm iterating through an outside object which, itself, holds numeruos objects. Those objects each hold various primitive data types. I have made the outer objects readOnly, non-config, etc, but can't figure out how to do likewise for individual props, the innermost props.

So, if outer.inner.prop === "Hello", I want to make that value readOnly.

Thanks!

UPDATE

I just figured this out, it was all in the for loop I was using to iterate over props. Now I've actually get data descriptors for the props, even the primitive ones. :) Thanks all!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

只有一腔孤勇 2024-11-23 05:17:04

您必须迭代内部对象,因为无法使用标准 ES5 方法深度冻结对象。

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

编辑:
如果您不想冻结,也适用于defineProperty

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

You have to iterate through the inner object, since there is no way to deep-freeze an object using standard ES5 methods.

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

Edit:
Also works for defineProperty if you don't want to freeze:

function deepWriteProtect(obj) {
    Object.keys(obj).forEach(function (key) {
        if (typeof obj[key] == 'object')
            deepWriteProtect(obj[key]);
        Object.defineProperty(obj, key, { writable: false });
    });
}
失与倦" 2024-11-23 05:17:04

我不能 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

I'm not 100% sure I understand your question correctly, but from what I gather you are asking for private variables. If so, that can be easily achieved using closures.

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
雨夜星沙 2024-11-23 05:17:04

以下 (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 可以被覆盖。

Would the following (ES5) example help? It creates an empty constructor, with a getter for property a (and no setter, so de facto a is read only):

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

Not using ES5 you can do

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

But that is not 100% failsafe: Obj.prototype.getA can be overwritten.

平生欢 2024-11-23 05:17:04

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

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

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

object.x = 100;

不会有任何效果。

Here is a jsfiddle showing how you can use ES5 getter/setter definitions to make a property of an object something that can only be fetched. The code looks like this:

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

Of course the getter could obtain the value of the property ("x") from anywhere, like a closure from a constructor or something. The point is that the setter simply does not change the value, so attempts to change it:

object.x = 100;

will not have any effect.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文