0

防止对象扩展—freeze vs seal vs preventExtensions

 1 year ago
source link: https://www.fly63.com/article/detial/12466
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

当涉及到在JavaScript中防止修改/更新对象时,我们比较熟悉的可能是Object.freeze方法,它能够做到完全阻止对象扩展。但除了完全阻止扩展外,javascript还可以做到部分阻止扩展,下面就让我们来一起了解下阻止对象扩展的一些常用方法。

  • 完全阻止扩展。
    • 无法添加新属性或更新现有属性或删除现有属性。
  • 部分阻止扩展
    • 无法添加新属性但能够更新现有属性。允许删除现有属性。
    • 无法添加新属性但能够更新现有属性。不允许删除现有属性。

JavaScript 提供了以下三种对象方法来分别满足所有这些场景。

Object.freeze()
Object.preventExtension()
Object.seal()

我们将逐一介绍这些方法以及它们如何按此顺序工作。

方法Object.freeze()

该Object.freeze()方法冻结一个对象。正如我之前提到的,它提供了完全防止对象扩展的能力。即不能将新属性添加到对象,也不能更新现有属性。

以下面的例子为例。

const user = {
  name: '南玖',
  gender: '男',
  hobby: {
    name: 'fe'
  }
}

Object.freeze(user)

user.name = 'nanjiu'
user.age = 18
delete user.gender
console.log(user)

这里我们对user修改name属性,以及新增age属性,删除gender属性,都是无法生效的。

6455c615eb11c.jpg

但这里要注意的一件事是该Object.freeze()方法只能“冻结”对象的「顶层属性」。嵌套对象仍然可以扩展。

因此,由于在user内部的hobby属性是个对象,所以我们仍然可以对这个hobby属性进行扩展

user.hobby.name = 'ux'
user.hobby.years = 3
6455c61b1c4de.jpg

所以如果你想用Object.freeze()冻结嵌套对象,则有必要使用它来包装嵌套对象。

Object.freeze(user.hobby);

user.hobby.name = 'ui';
user.hobby.address = 'shanghai';
// 不生效

方法Object.preventExtension()

该Object.preventExtensions()方法阻止将新属性添加到对象,但仍然可以更新现有属性。

以下面的例子为例。

const user = {
  name: '南玖',
  gender: '男',
  hobby: {
    name: 'fe'
  }
}

Object.preventExtensions(user)

user.name = 'nanjiu'
user.age = 18 // 不生效

user.hobby.name = 'ux'
user.hobby.years = 3

console.log(user)

如您所知,当user对象被方法包装时Object.preventExtensions(),允许更新user对象的name的,但是当添加一个新属性age时,则不会生效

6455c621504a0.jpg

此外,在使用该Object.preventExtensions()方法时,允许像这样删除现有属性。

delete user.name

与Object.freeze()类似,Object.preventExtensions()方法也不能阻止嵌套对象的扩展。因此,如果是这种情况,则有必要像这样包装嵌套对象。

Object.preventExtensions(user.hobby)

方法Object.seal()

最后,该Object.seal()方法密封了一个对象。该方法的工作方式与Object.preventExtensions()类似,使用该Object.seal()方法时的不同之处在于,无法删除现有属性。

以下面的例子为例。

const user = {
  name: '南玖',
  gender: '男',
  hobby: {
    name: 'fe'
  }
}

// Object.freeze(user)
// Object.preventExtensions(user)
Object.seal(user)

user.name = 'nanjiu'
user.age = 18  // 不生效

delete user.gender  // 不生效

user.hobby.name = 'ux'
user.hobby.years = 3

console.log(user)
6455c6277b434.jpg

但是不允许删除现有属性。

Object.freeze()和方法类似Object.preventExtensions(),Object.seal()方法也不能阻止嵌套对象的扩展。因此,如果是这种情况,则有必要像这样包装嵌套对象。

Object.seal(user.hobby)
来源公众号:前端南玖

链接: https://www.fly63.com/article/detial/12466


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK