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

Javascript 冻结对象的现有属性,但允许对象可扩展,javascript,node.js,Javascript,Node.js,所以我一直在看Object.freeze()和Object.seal() Object.freeze()-将使所有现有属性不可写,并且不允许添加任何新属性 Object.seal()-“密封对象会阻止添加新属性,并将所有现有属性标记为不可配置。” 我正在寻找一种方法,使所有现有属性“冻结”(不可写),但允许添加新属性 这有速记吗 手动执行我想要的操作的方法是: let freezeExistingProps = obj => { Object.keys(obj).forEach(k =

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

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

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

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

这有速记吗

手动执行我想要的操作的方法是:

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

上面的函数在冻结对象上现有的顶级属性(它不会覆盖它们,只会将它们更改为不可写)方面出人意料地工作得很好,但我希望有一种更正式/更快捷的方法来完成上述操作。

好吧,如果你想以冻结的方式执行,那么立即冻结它,设置另一个对象的原型可能会有所帮助,但它会返回一个副本(将原始对象作为原型指向),其格式与您想要的完全相同。显然有一些优点和缺点,因为属性不是直接属性,但是如果我们需要所有的键,我们可以通过它的
\uuuu proto\uuuu
找到它(假设您有一个专用用例)

那么,再来一次

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

现在看看A并改变一些B道具。

你可能想考虑把你的对象克隆成一个额外属性的新对象。这也是一个非常好的实践(寻找不变性

例如:

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

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

const personWithAge = setAge(person, 24);

嗯。。。有趣的。。。但我并没有听说JavaScript中存在这样的东西。是的,我真的很惊讶这并没有作为对象的官方方法存在(比如
Object.freezeExistingProps(obj)
,但是手动方式是可行的……出于好奇,您的用例是什么?我需要共享对象,但不希望在共享后修改现有属性。例如,假设超类上的静态属性X,您希望在所有实例之间共享其数据,但不希望子实例修改X或任何子属性但是在当前的方式下,这个
writeable:false
是可还原的,对吗?是的,但我需要克隆任意对象。不仅如此,我还需要进行深度克隆,而不是浅层克隆。在您的示例中,如果person或age是一个对象,它将保留对原始对象的引用。