JavaScript的Object.seal()

原文:Object.seal() in JavaScript

seal()函数可以防止对象添加或移除属性,同时仍然允许修改已有的属性,本文介绍了一些相关知识。

Object.seal()函数可以防止JavaScript对象添加、移除或重新配置属性。

1
2
3
4
5
6
7
8
9
10
11
12
const sealed = Object.seal({ answer: 42 });

sealed.answer = 43; // OK

// TypeError: Cannot delete property 'answer' of #<Object>
delete sealed.answer;

// TypeError: Cannot add property newProp, object is not extensible
sealed.newProp = 42;

// TypeError: Cannot redefine property: answer
Object.defineProperty(sealed, 'answer', { enumerable: false });

seal()Object.freeze()函数有些相似,关键不同在于:seal后的对象仍然可以编辑已有属性,但freeze后的对象不能编辑。

1
2
3
4
5
6
const sealed = Object.seal({ answer: 42 });
const frozen = Object.freeze({ answer: 42 });

sealed.answer = 43; // ok
// TypeError: Cannot assign to read only property 'answer' of object '#<Object>'
frozen.answer = 43;

freeze()类似,在严格模式seal后的对象添加、移除或重新配置属性会抛出异常,而非严格模式只是失败但不报错。

seal()函数也有些类似于Object.preventExtensions()函数,但后者只是防止向对象添加新属性,仍然可以移除或重新配置已有属性。

何时使用seal()

生产环境中,freeze()函数更常用一些,seal()函数很少见。可能会用到seal()的一个场景是对Node.js中global对象的保护。

1
2
3
Object.seal(global);

global.newProp = 42; // TypeError

一些npm包,例如safe-buffer,有意的修改了已有的global中的变量,但要防止其他npm包无意间添加新的global变量。诚然对global使用seal()在Node.js社区中并不常见,当然也不是既定的最佳实践,但可以试试——有惊喜(译注:没发现有啥惊喜)。