JavaScript:向密封对象添加属性会引发类型错误异常吗?

发布于 2024-10-27 18:22:47 字数 1255 浏览 0 评论 0原文

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

有什么想法吗?

Suppose I've got something like this in JavaScript:

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

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

So, what's the correct behavior? It's not in strict-mode, so I assumed that obj.address line would simply be ignored. However, that is not the case since it throws in Chrome. I'm looking at the tests for V8 and it seems like it should only throw in strict-mode:

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

and here's some code from that file:

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);

btw, there are the tests from strict mode, where my example will clearly throw: http://code.google.com/p/v8/source/browse/branches/bleeding_edge/test/mjsunit/strict-mode.js?spec=svn7250&r=7250

Any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甲如呢乙后呢 2024-11-03 18:22:47

Object.seal 做了两件事。

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

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

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

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

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

Object.seal does 2 things.

1) Sets objects's internal [[Extensible]] attribute to false.

2) Iterates over all of object's own properties and sets their internal [[Configurable]] attribute to false.

This pretty much means that you can't add any properties to an object after it's being sealed. Note that existing properties can still be modified, as long as an object is not frozen (or if a property that's being assigned to is not made non-writable explicitly).

In your case, you're adding another property to a sealed object, so in ES5-non-strict it should be ignored whereas in ES5-strict it should result in TypeError (as you can see from 11.3.1 (Simple Assignment); more specifically you can track it down to [[CanPut]] which pretty much returns the value of [[Extensible]] — false — in this case, and then [[Put]] either throws, if it's strict mode, or doesn't).

So nope, Chrome should not be throwing here (in non-strict mode).

傲性难收 2024-11-03 18:22:47

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

IE9: doesn't throw
Chrome: throws
Firefox 4: trows only in strict-mode code

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文