2

假设我在 JavaScript 中有这样的东西:

var obj = { name: "Luis" };
Object.seal( obj );

obj.address = "Fx"; //what should happen here?

那么,正确的行为是什么?它不在严格模式下,所以我假设 obj.address 行将被忽略。但是,情况并非如此,因为它会抛出 Chrome。我正在查看 V8 的测试,它似乎应该只在严格模式下抛出:

object.seal 测试代码: http ://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/object-seal.js?spec=svn7379&r=7379

这是该文件中的一些代码:

Object.seal(obj);

// Make sure we are no longer extensible.
assertFalse(Object.isExtensible(obj));
assertTrue(Object.isSealed(obj));

// We should not be frozen, since we are still able to
// update values.
assertFalse(Object.isFrozen(obj));

// We should not allow new properties to be added.
obj.foo = 42;
assertEquals(obj.foo, undefined);

顺便说一句,有来自严格模式的测试,我的例子会清楚地抛出:http ://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/strict-mode.js?spec =svn7250&r=7250

有任何想法吗?

4

2 回答 2

3

Object.seal做两件事。

1) 将对象的内部 [[Extensible]] 属性设置为 false。

2) 遍历对象自身的所有属性并将其内部 [[Configurable]] 属性设置为 false。

这几乎意味着您不能在对象被密封后添加任何属性。请注意,只要对象未冻结(或者如果分配给的属性未明确设为不可写),则仍然可以修改现有属性

在您的情况下,您正在向密封对象添加另一个属性,因此在 ES5-non-strict 中它应该被忽略,而在 ES5-strict 中它应该导致TypeError(正如您从11.3.1 (Simple Assignment)中看到的那样;更具体地说,您可以将其追踪到 [[CanPut]] ,它几乎返回 [[Extensible]] 的值 - false - 在这种情况下,然后 [[Put]] 要么抛出,如果它是严格模式,或者不' t)。

所以不,Chrome 不应该扔在这里(在非严格模式下)。

于 2011-03-30T04:17:01.320 回答
1

IE9:不抛出
Chrome:抛出
Firefox 4:仅在严格模式代码中抛出

于 2011-03-29T22:13:36.740 回答