<强>=与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详解