在 JavaScript 的对象中,我们有时会需要禁止属性的添加、删除或修改。为了满足这类需求,ES7 引入了 Object.seal() 和 Object.freeze() 两种方法。这篇文章将详解这两种方法的使用,帮助读者更好地理解它们的设计和实现。
Object.seal()
Object.seal() 方法可以将一个对象封闭,即防止新属性的添加和现有属性的删除。已有属性仍然可以被修改,但不能被转换为访问器属性(即 setter 和 getter)。语法如下:
Object.seal(obj)
其中,obj 是需要被封闭的对象。下面通过示例代码来说明 Object.seal() 的用法:
let obj = { name: 'Tom', age: 18 } Object.seal(obj) obj.age = 20 // 修改已有属性 console.log(obj.age) // 输出 20 obj.gender = 'male' // 添加新属性 console.log(obj.gender) // 输出 undefined delete obj.age // 删除已有属性 console.log(obj.age) // 输出 20
从上面的例子可以看出,使用 Object.seal() 方法封闭了 obj 对象,因此虽然修改已有属性的值可以生效,但添加新属性和删除已有属性都不起作用。
需要注意的是,Object.seal() 方法只是针对第一层属性生效,而不是递归作用于所有属性。也就是说,如果 obj 的某个属性是一个对象,那么该对象中的属性仍然可以添加、删除和修改。
Object.freeze()
Object.freeze() 方法可以将一个对象冻结,即防止对已有属性值的修改和对新增属性的添加、删除。已有属性仍然可以被访问。语法如下:
Object.freeze(obj)
其中,obj 是需要被冻结的对象。下面通过示例代码来说明 Object.freeze() 的用法:
let obj = { name: 'Tom', age: 18 } Object.freeze(obj) obj.age = 20 // 修改已有属性 console.log(obj.age) // 输出 18 obj.gender = 'male' // 添加新属性 console.log(obj.gender) // 输出 undefined delete obj.age // 删除已有属性 console.log(obj.age) // 输出 18
从上面的例子可以看出,使用 Object.freeze() 方法冻结了 obj 对象,因此无论是修改已有属性的值、添加新属性还是删除已有属性,都不起作用。
需要注意的是,同样地,Object.freeze() 方法只是针对第一层属性生效,而不是递归作用于所有属性。如果 obj 对象的某个属性是一个对象,那么该对象中的属性仍然可以添加、删除和修改。
使用注意事项
- Object.seal() 和 Object.freeze() 方法均为浅封装,即只作用于对象本身的属性,不包括嵌套对象的属性。
- 在使用 Object.freeze() 方法时,如果对象的某个属性是引用类型,则该属性的值实际上是该引用类型的地址,因此引用类型的属性值可以被修改。
- Object.seal() 和 Object.freeze() 方法都是不可逆的,一旦执行后,就不能撤销。
- 如果需要对对象的所有属性进行深度封装,可以使用第三方库来实现,比如 lodash 的 deepFreeze() 方法。
总结
Object.seal() 和 Object.freeze() 方法是 ES7 中用来对对象进行封装的方法,它们可以有效地保护对象不被意外修改和被非法访问。需要注意的是,这两种方法都是浅封装,只作用于对象本身的属性,不包括嵌套对象的属性。如果需要对对象的所有属性进行深度封装,可以使用第三方库来实现。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ae304fadd4f0e0ff7be024