JavaScript的Object.defineProperty详解

  

<强>=与Object.defineProperty

  

为JavaScript对象新增或者修改属性,有两种不同方式:直接使用=赋值或者使用Object.defineProperty()定义。如下:

     //示例1   var obj={};//直接使用=赋值   obj。=1;//使用Object.defineProperty定义   Object.defineProperty (obj,“b”,   {   值:2   });      console.log (obj)//打印“{1,b: 2}”   之前      

这样看两者似乎没有区别,对吧?但是,如果使用Object.getOwnPropertyDescriptor()查看obj.a与obj。b的属性的描述描述符(属性描述符)时,会发现=与Object.defineProperty并不一样:

     //示例2   var obj={};      obj。=1;      Object.defineProperty (obj,“b”,   {   值:2   });      console.log(对象。getOwnPropertyDescriptor (obj, " a "));//打印“{价值:1、可写:没错,可列举的:没错,可配置:真正}”   console.log(对象。getOwnPropertyDescriptor (obj, " b "));//打印”{值:2,可写:假的,姑且称之为:假的,可配置的:虚假}”      

可知,使用=赋值时,属性的属性描述符值是可以修改的,而可写,可列举的和可配置的都为真的。

  

而使用Object.defineProperty()定义的属性的属性描述符可写,可列举的和可配置的默认值为false,但是都可以修改。对于可写,可列举的和可配置的含义,从名字就不难猜中,后文也会详细介绍。

  

使用=赋值,等价于使用Object.defineProperty()定义时,同时将可写,可列举的和可配置的设为真。代码示例3和4是等价的:

     //示例3   var obj={};      obj.name=" Fundebug”;   console.log(对象。getOwnPropertyDescriptor (obj, "名称"));//打印{值:“Fundebug”,可写:没错,可列举的:没错,可配置:真正的}   之前         //示例4   var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”,   可写:没错,   可列举的:真的,   可配置:真   });   console.log(对象。getOwnPropertyDescriptor (obj, "名称"));//打印{值:“Fundebug”,可写:没错,可列举的:没错,可配置:真正}      

<强> Object.defineProperty()

  

使用Object.defineProperty()定义时若只定义值,则可写,可列举的和可配置的默认值为假的。代码示例5和6是等价的:

     //示例5   var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”   });   console.log(对象。getOwnPropertyDescriptor (obj, "名称"));//打印{值:“Fundebug”,可写:假的,姑且称之为:假的,可配置的:虚假}   之前         //示例6   var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”,   可写:假的,   可列举的:假的,   可配置:假   });   console.log(对象。getOwnPropertyDescriptor (obj, "名称"));//打印{值:“Fundebug”,可写:假的,姑且称之为:假的,可配置的:虚假}   之前      

由于可写,可列举的和可配置的都是假的,导致obj.name属性不能赋值,不能遍历而且不能删除:

     //示7例   var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”   });//可写为假,无法赋值   obj.name="云麒”;   console.log (obj.name);//打印“Fundebug”//枚举为假,无法遍历   console.log(种(obj));//打印“[]”//可配置为假,无法删除   删除obj.name;   console.log (obj.name);//打印“Fundebug”   之前      

若在严格模式(“使用严格”)下,示例7中的代码会报错,下文可见。

  

<强>可写的

  

可写为假时,属性不能再次赋值,严格模式下会报错“不能分配阅读>//示例8   “使用严格的”      var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”,   可写:假的,   可列举的:真的,   可配置:真   });      obj.name="云麒”;//报错”未捕获TypeError:不能分配阅读>//示例9   “使用严格的”      var obj={};      Object.defineProperty (obj,“名字”,   {   价值:“Fundebug”,   可写:没错,   可列举的:假的,   可配置:真   });      console.log(种(obj))//打印“[]”   之前      

可列举的为真时,属性可以遍历,这一点读者不妨自行测试。

JavaScript的Object.defineProperty详解