如果我定义一个对象并将其可配置属性设置为 false,但保留所有其他属性,然后尝试将该对象的 writable 属性设置为 false,然后返回 true,则会引发 TypeError。
以下是我如何执行此操作的详细说明,尽管我已尝试通过仅更改点表示法中的一个对象数据描述符以及更改对象文字中对象的所有数据描述符来实现此目的,但这两种形式都不起作用。
// simple object, and the data descriptor
var o = {name : "tom"},
dataDesc = Object.getOwnPropertyDescriptor(o, "name");
noConfig();
alert(dataDesc.writable); // alerts true
readOnly();
alert (dataDesc.writable); // alerts false
writable();
alert (dataDesc.writable); // error is thrown within writable() - alerts true
// early in the script, altering only configurable property
function noConfig(){
dataDesc.configurable = false;
}
// later in the script, altering only writable property
function readOnly(){
dataDesc.writable = false; // configurable = false; writable = false;
Object.defineProperty(o, "name", dataDesc); // works finely
}
function writable(){
try{
dataDesc.writable = true; // configurable = false; writable = true;
Object.defineProperty(o, "name", dataDesc); // throws TypeError
}catch(e){
alert(e); // alerts: "TypeError: Cannot redefine property: defineProperty"
}
}
我在规范中找不到任何帮助,但关于 DefineProperty 的 MDC 文章指出,即使在对象属性呈现为不可配置之后,仍然可以修改可写数据描述符。其他所有都不能,但可写可以。
那么,这是 Chrome 中的问题,还是我做错了?
/* 更新 */
这已解决 - 只需阅读规范 8.12.9 第 10.ai 节
If I define an object and set its configurable property to false, but leave all other props alone, and later attempt to set that object's writable prop to false, then back to true, a TypeError is thrown.
Here's a breakdown of how I'm doing this, although I have attempted this by altering only one object data descriptor in dot notation, and also by altering all data descriptors of the object in object literal, and neither form has worked.
// simple object, and the data descriptor
var o = {name : "tom"},
dataDesc = Object.getOwnPropertyDescriptor(o, "name");
noConfig();
alert(dataDesc.writable); // alerts true
readOnly();
alert (dataDesc.writable); // alerts false
writable();
alert (dataDesc.writable); // error is thrown within writable() - alerts true
// early in the script, altering only configurable property
function noConfig(){
dataDesc.configurable = false;
}
// later in the script, altering only writable property
function readOnly(){
dataDesc.writable = false; // configurable = false; writable = false;
Object.defineProperty(o, "name", dataDesc); // works finely
}
function writable(){
try{
dataDesc.writable = true; // configurable = false; writable = true;
Object.defineProperty(o, "name", dataDesc); // throws TypeError
}catch(e){
alert(e); // alerts: "TypeError: Cannot redefine property: defineProperty"
}
}
I could find nothing to help in the spec, but the MDC article for defineProperty states that, even after an object property is rendered unconfigurable, the writable data descriptor can still be modified. All others cannot, but writable can.
So, is this something in Chrome, or am I doing this wrong?
/* UPDATE */
This has been resolved - just read the spec 8.12.9 section 10.a.i
发布评论
评论(1)
该错误不是来自
dataDesc.writable = true;
,而是来自Object.defineProperty(o, "name", dataDesc);
...这是正确的,因为{name : "tom"}
确实 已经定义了name
属性。这是正确的行为,您能够更改
可写
并且不能能够重新定义name
属性。我认为混乱来自于行为,你不需要调用
.defineProperty()
来使.writable
生效,你可以在这里测试。注意:我在上面的例子中注释掉了
.configurable = false
,这会锁定属性属性并且不允许您进一步更改writable
,将其保留在原始代码中的false
中。The error isn't coming from
dataDesc.writable = true;
, it's coming fromObject.defineProperty(o, "name", dataDesc);
...which is correct, since{name : "tom"}
does already have aname
property defined.This is the correct behavior, you are able to change
writable
and not able to redefine thename
property.I think the confusion comes from the behavior, you don't need to call
.defineProperty()
for.writable
to take effect, you can test it here.Note: I commented out
.configurable = false
in the above example, which would lock the property attributes and not allow you to changewritable
further, leaving it stuck infalse
in your original code.