如果我定义了一个对象并将其可配置属性设置为false,但不考虑其他所有道具,后来又尝试将该对象的可写道具设置为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"
    }
}


我在规范中找不到任何帮助,但是MDC上defineProperty的文章指出,即使在对象属性变为不可配置之后,可写数据描述符仍然可以被修改。所有其他人不能,但可写。

那么,这是Chrome中的问题吗,还是我做错了吗?

/ *更新* /

该问题已解决-只需阅读规范8.12.9第10.a.i节

最佳答案

错误不是来自dataDesc.writable = true;,而是来自Object.defineProperty(o, "name", dataDesc); ...这是正确的,因为{name : "tom"}已经定义了name属性。

这是正确的行为,您可以更改writable,而不能重新定义name属性。

我认为混乱来自行为,您无需调用.defineProperty()即可使.writable生效,you can test it here

注意:在上面的示例中,我注释了.configurable = false,这将锁定属性属性,并且不允许您进一步更改writable,而将其保留在原始代码的false中。

09-30 16:30