Javascript 对于不变性,使用Object.defineProperty和Object.freeze有什么区别?

Javascript 对于不变性,使用Object.defineProperty和Object.freeze有什么区别?,javascript,ecmascript-6,immutability,Javascript,Ecmascript 6,Immutability,MDN文档作为解决方案,通过防止初始化后对类进行任何更改,使类不可变,如下所示: class ExampleA { constructor(x) { this.x = x; Object.freeze(this); } } 但是,我看到其他人通过使用like so也能达到同样的效果: 乍一看,这两种方法似乎达到了相同的目的,那就是我希望this.x是不可变的。最重要的是,使用Object.defineProperty()可以选择使哪些属性不可变,

MDN文档作为解决方案,通过防止初始化后对类进行任何更改,使类不可变,如下所示:

class ExampleA {
    constructor(x) {
        this.x = x;
        Object.freeze(this);
    }
}
但是,我看到其他人通过使用like so也能达到同样的效果:

乍一看,这两种方法似乎达到了相同的目的,那就是我希望
this.x
是不可变的。最重要的是,使用
Object.defineProperty()
可以选择使哪些属性不可变,而不是像
Object.freeze()那样使所有属性都不可变


所以我需要问:就实现不变性而言,首选的方法是什么?使用
Object.defineProperty()
覆盖
Object.freeze()
Object.freeze
Object
级别起作用,而
Object.defineProperty
在属性级别起作用。两者都可以控制对象类型的易变性,但后者可以做得更多。简单地说,如果一个属性包含另一个对象类型,则该对象既不受
object.freeze
的影响,也不受
object.defineProperty
的影响,但仍然是可变的


因为只有两种工具都能实现不可变,只有浅而深的不变性是昂贵的,所以我建议把不可变性看作是一种策略,而不是明确地执行它。让我选择哪些属性使其不可变,而不是像Object.freeze()那样使任何东西都不可变。此外,

Object.defineProperty()
还可以做其他有用的事情。(顺便说一句,您知道即使在冻结对象之后,如果其属性引用其他对象,这些对象仍然可以更改,除非它们也被冻结了?)
class ExampleB {
    constructor(x) {
        Object.defineProperty(this, "x", {value: x});
    }
}