02 September 2013

这篇博客旨在快速复习如何在 JavaScript 中保护对象。有 3 种程度的保护:

  1. 最弱的是阻止扩展,
  2. 稍强的是封闭对象,
  3. 最强的是冻结对象。

阻止扩展

Object.preventExtensions(obj)

使对象不能再添加属性。例如

var obj = { foo: 'a' };
Object.preventExtensions(obj);

现在,在宽松模式下添加属性会静默失败:

> obj.bar = 'b';
> obj.bar
undefined

而在严格模式[1]下会抛出一个错误,我们通过一个 IIFE[2] 使用严格模式。

> (function () { 'use strict'; obj.bar = 'b' }());
TypeError: Can't add property bar, object is not extensible

但是,仍然可以删除属性。

> delete obj.foo
true
> obj.foo
undefined

检查对象是否可扩展

Object.isExtensible(obj)

检查 obj 是否可扩展:

> Object.isExtensible(obj)
false

封闭对象

Object.seal(obj)

阻止扩展,并使所有属性“不可配置”。后者意味着属性的特性不可修改。只读的属性保持只读,可枚举的属性仍可枚举,等等。

(顺便说一句,因为历史原因,JavaScript 允许把不可配置的属性从可写改为只读。)

下面的例子演示了封闭使所有属性不可配置。

> var obj = { foo: 'a' };

> Object.getOwnPropertyDescriptor(obj, 'foo')  // before sealing
{ value: 'a',
  writable: true,
  enumerable: true,
  configurable: true }

> Object.seal(obj)

> Object.getOwnPropertyDescriptor(obj, 'foo')  // after sealing
{ value: 'a',
  writable: true,
  enumerable: true,
  configurable: false }

你仍然可以改变属性 foo:

> obj.foo = 'b';
'b'
> obj.foo
'b'

但是你不能改变它的特性:

> Object.defineProperty(obj, 'foo', { enumerable: false });
TypeError: Cannot redefine property: foo

Additionally, obj is not extensible, any more. 此外,obj 不再可扩展。

检查对象是否是封闭的

Object.isSealed(obj)

检查 obj 是否是封闭的:

> Object.isSealed(obj)
true

冻结对象

Object.freeze(obj)

是所有属性不可写,并封闭对象。也就是说,对象不可扩展,所有属性为只读并不可修改。

var point = { x: 17, y: -5 };
Object.freeze(point);

在宽松模式中,将再次静默失败:

> point.x = 2;  // no effect, point.x is read-only
> point.x
17

> point.z = 123;  // no effect, point is not extensible
> point
{ x: 17, y: -5 }

在严格模式中则抛出一个错误:

> (function () { 'use strict'; point.x = 2 }());
TypeError: Cannot assign to read-only property 'x'

> (function () { 'use strict'; point.z = 123 }());
TypeError: Can't add property z, object is not extensible

检查对象是否是冻结的

Object.isFrozen(obj)

检查 obj 是否是冻结的:

> Object.isFrozen(point)
true

参考文献

  1. JavaScript’s strict mode: a summary
  2. JavaScript variable scoping and its pitfalls
  3. Object properties in JavaScript

原文:Protecting objects in JavaScript



blog comments powered by Disqus