冻结对象的现有属性,但允许对象可扩展

时间:2017-07-22 20:47:23

标签: javascript node.js

所以我一直在关注Object.freeze()Object.seal()

Object.freeze() - 将使所有现有属性不可写,并且不允许添加任何新属性。

Object.seal() - “密封对象可防止添加新属性,并将所有现有属性标记为不可配置。”

我正在寻找一种方法来使所有现有的属性“冻结”(不可写),但允许添加新属性。

这样做有简写吗?

手动方式做我想要的是:

let freezeExistingProps = obj => {
  Object.keys(obj).forEach(k => {
     Object.defineProperty(obj, k, {
         writable: false
      });
  });
};

以上函数可以很好地冻结对象上的现有顶级属性(它不会覆盖它们,只是将它们更改为不可写),但我希望可能有更正式/更快的方式做上面的事。

3 个答案:

答案 0 :(得分:1)

好吧,如果你想以冻结的方式进行,然后立即冻结,并设置为另一个对象的原型可能会有所帮助,但它会返回一个副本(指向原始对象作为原型),完全按照你想要的形式。显然有一些优点和缺点,因为属性不会是直接属性,但如果我们需要所有键(假设你有一个专用的用例),我们可以通过__proto__找到它。

所以,再试一次

function freezeExistingProps (obj){
    var OBJECT = function(){};
    Object.freeze(obj)
    OBJECT.prototype = obj;
    return new OBJECT();
}

答案 1 :(得分:1)

您可以执行以下操作:

instance -> frozen static proto -> dynamic proto

一些样本:

function freeze(stat,dyn){
  Object.setPrototypeOf(stat,dyn);
  Object.freeze(stat);
}

var a={unchangeable:1};
var b={changeable:2}
freeze(a,b);

现在看一下 a 并更改一些 b 道具。

答案 2 :(得分:0)

您可能需要考虑将对象克隆到具有额外属性的新对象。这也是一种非常好的做法(寻找不变性)。

一个例子:

const setAge = (person, age) => ({ ...person, age });

const person = {
  firstName: 'Luke',
  lastName: 'Skywalker',
};

const personWithAge = setAge(person, 24);