本文介绍ECMAScript 5中创建防篡改对象的三种方式。通过Object.preventExtensions使对象不可扩展,利用Object.seal密封对象以禁止删除属性,使用Object.freeze冻结对象以禁止修改属性值。文章详细对比了各方法对[[Configurable]]和[[Writable]]特性的影响,并说明了严格模式下的行为差异。
JavaScript防篡改对象:不可扩展、密封与冻结详解
本文介绍了在JavaScript中构建防篡改对象的具体实现方式,供开发者参考。
在早期JavaScript版本中,开发人员可能意外修改他人代码,甚至重写原生对象。引入ECMAScript 5后,开发者可以定义防篡改对象来避免此类风险。
需要注意的是,一旦将对象设置为防篡改状态,该操作不可撤销。
不可扩展对象
1 不可扩展对象
默认情况下,所有对象均可扩展,允许自由添加属性和方法。调用 Object.preventExtensions(person) 后,对象将变为不可扩展状态:
<script type="text/javascript">
var person = {name: "deniro"};
// person.age = 29;
// console.log(person.age);
console.log(Object.isExtensible(person));//true
Object.preventExtensions(person);
person.age = 15;
console.log(person.age);//undefined
console.log(Object.isExtensible(person));//false
</script>
运行结果:

在非严格模式下,尝试为对象添加新成员会静默失败;而在严格模式下,则会抛出错误。
尽管对象无法添加新成员,但仍可修改或删除已有成员。使用 Object.isExtensible() 可以检测对象是否处于可扩展状态。
密封的对象
2 密封的对象
密封对象不仅不可扩展,其所有现有成员的 [[Configurable]] 特性也被设为 false。这意味着无法删除该对象的属性和方法,但允许修改属性值:
<script type="text/javascript">
var person = {name: "deniro"};
console.log(Object.isExtensible(person));//true
console.log(Object.isSealed(person));//false
Object.seal(person);//密封对象
console.log(Object.isExtensible(person));//false
console.log(Object.isSealed(person));//true
person.age = 29;
console.log(person.age);//undefined
delete person.name;
console.log(person.name);//deniro
</script>
运行结果:

与不可扩展对象类似,在非严格模式下删除已有成员会静默失败;在严格模式下则抛出错误。
冻结的对象
3 冻结的对象
冻结是防篡改的最高级别。冻结对象既不可扩展,也是密封的,且其数据属性的 [[Writable]] 特性被设为 false,即属性值不可修改:
<script type="text/javascript">
var person = {name: "deniro"};
console.log(Object.isExtensible(person));//true
console.log(Object.isSealed(person));//false
console.log(Object.isFrozen(person));//false
Object.freeze(person);
console.log(Object.isExtensible(person));//false
console.log(Object.isSealed(person));//true
console.log(Object.isFrozen(person));//trueo
person.age = 29;
console.log(person.age);//undefined
delete person.name;
console.log(person.name);//deniro
person.name = "lily";
console.log(person.name);//deniro
</script>
运行结果:

对于JavaScript第三方库而言,冻结对象非常有用,因为这类库最担心被意外修改。
感兴趣的朋友可以使用本站在线HTML/CSS/JavaScript代码运行工具:http://tools.jb51.net/code/HtmlJsRun测试上述代码运行结果。
更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》
希望本文所述对大家JavaScript程序设计有所帮助。