为了看着不是那么累,本屌仍是决定宁愿把本系列多写几篇,每篇控制在必定长度,也方便看官们阅读。chrome
上一篇中提到“属性特性”这个概念,一个普通的数据属性具备:可写性、可枚举性、可配置性,若是把它的值也当作特性的话,即一个普通的数据属性就是:值(value)、可写性(writable)、可枚举性(enumerable)、可配置性(configurable);因为存取器属性没有可写性,所以存取器的特性能够分为:读取、写入、可枚举性和可配置性。函数
为了实现属性特性的查询和操做,ECMAScript5中定义了一个名为“属性描述符”的对象,用来表明那4个特性,经过调用Object.getOwnPropertyDescriptor()方法能够获取某个对象特定属性的属性描述符,对于不存在的属性和继承属性则返回undefined:测试
var o ={ x : 2, y : 3, get z(){ return this.x*this.y; }, set z(value){ this.x += value; this.y += value; } }; Object.getOwnPropertyDescriptor(o,"x"); //返回Object {value: 2, writable: true, enumerable: true, configurable: true} Object.getOwnPropertyDescriptor(o,"r"); //返回Object {get: function, set: function, enumerable: true, configurable: true}
经过Object.defineProperty()方法能够设置属性的特性,此函数须要传入3个参数,第一个是要修改的对象,第二个是要修改或建立的属性,第三个是属性描述符对象,若是操做成功,则返回这个被修改后的对象,以下所示:this
1 var o = {}; 2 Object.defineProperty(o,"x",{ 3 value:1, 4 writable:true, 5 enumerable:false, 6 configurable:true 7 }); 8 9 console.log(o.x); //返回1 10 Object.keys(o); //返回[],x是不可遍历的 11 12 o.x = 3; 13 console.log(o.x); //返回3 ,属性是可写的 14 15 Object.defineProperty("x",{writable:false}); 16 17 o.x = 6; //操做失败,说明x此时已是不可写的
当用该方法修改或新建属性特性时,没必要把所有4种属性特性都写出来,但对于新建立的属性来讲,默认的属性特性值为false或undefined,有一点要特别注意:该方法只能新建或修改自有属性,不能操做继承属性。spa
除了Object.defineProperty()之外,js还提供了一个Object.defineProperties()方法来批量操做属性的特性,也是返回修改后的对象,以下:code
1 var p =Object.defineProperties({},{ 2 x:{value:1, writable:false, enumerable:true, configurable:false}, 3 y:{value:3, writable:true}, 4 r:{get:function(){return this.x+this.y}, 5 set:function(value){this.x+=value;this.y+=value;}, 6 enumerable:true, 7 configurable:false 8 } 9 });
在《JavaScript权威指南》中,共列出了6条属性特征的规则,有点难记,感受仍是写一字不漏的放在这当字典比较好,碰到具体问题时多看几遍就记住了:对象
写到这里,忽然间有个疑问,若是把一个属性的特性修改成同时具备值特性和存取器属性会怎么样,结果在chrome的测试结果为失败,提示ypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>,因此有一样疑问的人就不用瞎折腾了。blog