【问题标题】:JavaScript: Adding properties to a sealed object should throw a typeerror exception?JavaScript:向密封对象添加属性应该引发类型错误异常?
【发布时间】:2011-03-29 20:41:21
【问题描述】:

假设我在 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

有什么想法吗?

【问题讨论】:

  • 为什么你认为它不应该抛出非严格代码?
  • 查看 kangax 对注释规范的链接。

标签: javascript ecmascript-5


【解决方案1】:

Object.seal 做了两件事。

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

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

这几乎意味着您在对象被密封后无法向其添加任何属性。请注意,现有的属性仍然可以修改,只要对象没有被冻结(或者如果分配给的属性没有显式地不可写)。

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

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

【讨论】:

  • 感谢您的链接。我查看了规范并了解 [[canput]] 和 [[put]] 是如何工作的。问题是找到在非严格模式下调用 [[put]] 的方式(因为异常抛出由传递给它的最后一个参数确定)。顺便说一句,带注释的版本在这里真的很有帮助!再次感谢。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 2018-04-25
    • 1970-01-01
    • 2023-03-12
    • 2021-10-26
    • 2011-11-09
    • 2013-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多