Javascript Object.seal()不会抛出异常

时间:2013-12-01 18:54:40

标签: javascript ecmascript-5

我想模仿类似固定对象的东西,这样就不会有新成员添加到对象中。 Object.seal(Obj)似乎是正确的方法,但是当我尝试创建新成员时它不会抛出异常。该成员未创建,但它是在沉默中发生的。

var O = { a: 111 }
Object.seal(O)
O.b = 222  <------ here the exception is expected (trying to add a member "b")
O.a = 333
console.log(O) // { a: 333 }

为什么有人想要这种沉默行为,为什么不抛出异常?

2 个答案:

答案 0 :(得分:4)

对密封对象的赋值行为随浏览器而变化。例如,最新版本的chrome就像你期望的那样。 出于实际目的,可以安全地假设在密封对象中添加成员仅在严格模式下抛出异常。

;(function () {
    'use strict';
    var O = { a: 111 }
    Object.seal(O)
    O.b = 222
    O.a = 333
    console.log(O) // { a: 333 }
}());

这个自动调用的匿名函数会抛出错误,正如您所期望的那样。 不幸的是,在旧的浏览器上,你不能依赖于polyfills等 https://github.com/kriskowal/es5-shim

事实上,Object原型上的seal方法避免了类型错误&#39;异常,但在调用时无声地失败 来自文档:

  

这应该没问题,除非你依赖安全和   这种方法的安全规定,你不可能获得   在传统引擎中。

答案 1 :(得分:2)

指定非可扩展对象的不存在属性的赋值为throw,但仅当赋值包含在strict-mode代码中时才指定。请参阅ES5.1 Annex C的第4项目。

如果您想确保获得例外,请确保使用“use strict”标记代码;

这样的赋值不会引入非严格代码的原因是为了保持与符合ECMAScript标准的ES3(或更旧版本)版本的代码的向后兼容性。在ES5之前不存在可扩展/不可扩展的概念,但是一些实现可能暴露了无法添加属性的主机对象(即,DOM对象)。使用ES3语义,不会抛出对这些对象的赋值。