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

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

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

Object.seal() – “密封一个对象,防止添加新的属性,并将所有现有属性标记为不可configuration。”

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

这样做有速记吗?

手动做我想做的是:

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

上面的函数工作起来非常好,可以冻结对象上的现有顶层属性(它不覆盖它们,只是将它们改为不可写),但是我希望可以有一个更正式/更快捷的方式来完成上述操作。

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

所以,只是另一个尝试

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

您可以执行以下操作:

 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); 

现在看看一个和改变一些B道具。

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

一个例子:

 const setAge = (person, age) => ({ ...person, age }); const person = { firstName: 'Luke', lastName: 'Skywalker', }; const personWithAge = setAge(person, 24);