控制一个对象或对象属性改变方式有下面几种。

Object.freeze()

一个被冻结的对象再也不能被修改、增删。非严格模式下修改、增删是无效的,严格模式会抛出异常(例如 Cannot assign to read only property 'x' of object)。

缺点:冻结只能做到浅冻结,如果被冻结对象的属性是对象的话,要做到完全冻结,需要递归冻结每个类型是对象的属性。

代码实现

const obj = { x: 1 } Object.freeze(obj) // 修改 obj.x = 2 // 删除 delete obj.x // 增加 obj.y = 1

Object.defineProperty

设置了writable: false的属性,是不能被修改,设置了configurable: false,不能被删除。非严格模式下修改、增删是无效的,严格模式会抛出异常(例如 Cannot assign to read only property 'x' of object)。

缺点:defineProperty也只能做到浅设置,如果被设置的属性是对象的话,要做到完全限制,需要递归设置每个类型是对象的属性。

代码实现

const obj = { x: 1 } Object.defineProperty(obj, 'x', { writable: false, configurable: false })

setter 模拟

把对应属性改造成一个setter,setter函数体里直接抛出异常

代码实现

const obj = { x: 1 } Object.defineProperty(obj, 'x', { set() { throw new Error('Cannot assign to property "x" of object') } })

缺点:setter可以通过delete删除