【问题标题】:Implement alternative to Object.seal, Object.freeze, Object.preventExtensions实现 Object.seal、Object.freeze、Object.preventExtensions 的替代方案
【发布时间】:2016-05-23 09:15:44
【问题描述】:

我需要以下功能。我想冻结对象的现有属性,但允许添加新属性。出于某种原因,似乎没有 Object.freezeExisting() 功能,我认为实现它可能是值得的,可以选择冻结原型的现有属性。

我不知道该怎么做。这是一些入门代码,但这根本不可能。我不太关心性能,它只需要 100% 工作。

Object.freezeExistingProps = function(obj, modifyProto){

    Object.keys(obj).forEach(function(key){

        const val = obj[key];

        Object.defineProperty(obj, key , {  //we simply overwrite existing prop
            value: val,
            writable: false, // important, I think
            enumerable: true,
            configurable: false
        });


    });

    return obj;

};

但我只需要对上述内容进行全面检查。我还需要一些关于如何沿着原型链走下去并在弄乱实际的 Object.prototype 之前以某种方式停止的信息。

【问题讨论】:

  • hasownproperty 是我猜你要找的那个。
  • 冻结原型的现有属性”没有多大意义。如果您不阻止扩展,无论如何都可以将原型换成其他对象。而您仅冻结原型链的一部分的意图使这一点更加可疑。您可能需要考虑将继承的属性复制到对象本身,然后冻结它们。

标签: javascript node.js ecmascript-6


【解决方案1】:

您可以轻松实现setIntegrityLevel algorithm,而无需自己阻止扩展:

Object.freezeExisting = function(o) {
    for (const key of Reflect.ownKeys(o)) {
        const desc = Object.getOwnPropertyDescriptor(o, key);
        if (!desc)
            continue;
        if ("value" in desc)
            Object.defineProperty(o, key, {configurable: false, writable: false});
        else
            Object.defineProperty(o, key, {configurable: false});
    }
    return o;
};

【讨论】:

  • 您从规范中删除了“如果 currentDesc 不是未定义”检查。但是对于像new Proxy({},{ownKeys:()=>["a"]}) 这样的代理来说,这可能是必要的,因为它们对它们的属性撒谎。
  • @Oriol:哦,我努力寻找currentDesc 对于来自ownKeys 的密钥的undefined 的情况,但失败了。但你是对的,代理可以做到这一点。已更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2022-12-11
  • 1970-01-01
  • 1970-01-01
  • 2021-10-26
  • 2016-10-01
相关资源
最近更新 更多