ES7 中的 Object.seal() 和 Object.freeze() 方法详解

在 JavaScript 的对象中,我们有时会需要禁止属性的添加、删除或修改。为了满足这类需求,ES7 引入了 Object.seal() 和 Object.freeze() 两种方法。这篇文章将详解这两种方法的使用,帮助读者更好地理解它们的设计和实现。

Object.seal()

Object.seal() 方法可以将一个对象封闭,即防止新属性的添加和现有属性的删除。已有属性仍然可以被修改,但不能被转换为访问器属性(即 setter 和 getter)。语法如下:

其中,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() 方法可以将一个对象冻结,即防止对已有属性值的修改和对新增属性的添加、删除。已有属性仍然可以被访问。语法如下:

其中,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 对象的某个属性是一个对象,那么该对象中的属性仍然可以添加、删除和修改。

使用注意事项

  1. Object.seal() 和 Object.freeze() 方法均为浅封装,即只作用于对象本身的属性,不包括嵌套对象的属性。
  2. 在使用 Object.freeze() 方法时,如果对象的某个属性是引用类型,则该属性的值实际上是该引用类型的地址,因此引用类型的属性值可以被修改。
  3. Object.seal() 和 Object.freeze() 方法都是不可逆的,一旦执行后,就不能撤销。
  4. 如果需要对对象的所有属性进行深度封装,可以使用第三方库来实现,比如 lodash 的 deepFreeze() 方法。

总结

Object.seal() 和 Object.freeze() 方法是 ES7 中用来对对象进行封装的方法,它们可以有效地保护对象不被意外修改和被非法访问。需要注意的是,这两种方法都是浅封装,只作用于对象本身的属性,不包括嵌套对象的属性。如果需要对对象的所有属性进行深度封装,可以使用第三方库来实现。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65ae304fadd4f0e0ff7be024