在 Firefox 和 Safari 中,我看到 Object.isExtensible()
为 true 的情况,我可以添加一个具有常规属性分配的新属性(即,o.x = y
),但是 Object.defineProperty()
抛出“TypeError: Object.defineProperty(...) is not extensible”。
这种情况发生在类型化数组中,也许其他类型也是如此。我正在尝试使用 isExtensible()
来确保我不会尝试在对象上定义属性。
我可以将 defineProperty 放在 try/catch 中,但我想了解这里发生了什么。有什么想法吗?
这是一个关于 jsfiddle 的例子:http://jsfiddle.net/justinfagnani/qvgnk/
还有代码:
function addProperty(o, name, value) {
if (Object.isExtensible(o)) {
Object.defineProperty(o, name, {'value': value});
return true;
}
return false;
}
console.log(addProperty(new Date(), 'foo', 1));
console.log(addProperty(new ArrayBuffer(), 'foo', 1));
这至少应该为每次调用打印 true 或 false。在 Firefox 中,它会抛出 ArrayBuffer。
最佳答案
Note: typed arrays are now in the ES6/ES2015 specification, where
ArrayBuffer
s are actually extensible. This answer is provided for prior reference.
Typed Array specification尽管它使用了 Web IDL,但并未对此明确说明任何内容描述创建的对象,其中说明如下:
Unless otherwise specified, the [[Extensible]] internal property of objects defined in this section has the value true.
我不确定他们为什么将其放入规范中,但他们可能选择使 [[Extensible]]
为真(即使它不可扩展)的一些原因包括:
- 希望允许来自特定函数/路径的扩展(为 false 时禁止)
- 保留允许扩展宿主对象的可能性(禁止从 false 更改为 true)
根据the ECMAScript specification (JavaScript 的“标准”版本),宿主对象是否抛出设置变量取决于实现(§8.6.2):
Host objects may implement these internal methods in any manner unless specified otherwise; for example, one possibility is that
[[Get]]
and[[Put]]
for a particular host object indeed fetch and store property values but[[HasProperty]]
always generates false. However, if any specified manipulation of a host object's internal properties is not supported by an implementation, that manipulation must throw aTypeError
exception when attempted.
规范给出的不变量均不适用于此实例,因此这在技术上是合法的。
注意澄清:即使 [[Extensible]]
为真,宿主对象的内部函数也不一定允许对象被扩展。如果 [[Extensible]]
为 false ( reference ),该规范仅要求不扩展主机对象:
The
[[DefineOwnProperty]]
internal method of a host object must not permit the addition of a new property to a host object if the[[Extensible]]
internal property of that host object has been observed by ECMAScript code to be false.
表 8/9 (§8.6.2) 中的规范中给出的描述本身具有误导性,因为它们仅涉及 native ECMAScript 对象,而不涉及宿主对象——这在表 8 之前的段落中特别指出,宿主对象是不受实现这些表中描述的属性的约束。
关于javascript - Object.isExtensible() 为真,但 Object.defineProperty() 抛出。为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19329049/