如何自定义属性的特性?javascript
用对象.属性的特性和自定义的属性的特性有什么区别?java
它的四大特性 writable enumerable configable 有什么区别?数组
先预习一个用对象.属性定义 ,属性的四大特性是以什么方式呈现的。spa
这时个属性的三大特性默认值都为true。prototype
代码演示:code
1 <script> 2 //用对象.属性定义的属性,它的三大特性都为true 3 function Foo(){} 4 Foo.prototype.age = 22 5 var obj = new Foo() 6 obj.name = "ziksang" 7 obj.addr = "上海" 8 obj.telephone = 15921848427 9 console.log(obj.name)//=>ziksang 10 obj.name = "博客园" //修改了name属性的值 11 console.log(obj.name) //=>博客园 由于此时定义的方式 writable为true,因此能够修改name的属性值 12 for( var p in obj){ //由于此时定义的方式,enumerable为true, 此时也是能够枚举的, 13 console.log(p) //用for in枚举能够把对象原型上的属性也枚举出来,由于原型上的属性也是用此定义属性,因此他的enumerable也为true 14 } 15 console.log(Object.keys(obj)) //用Object.keys(obj)方式枚举只能枚举对象自有的属性 16 delete obj.addr //删除对象上addr属性 17 console.log(obj.addr) //=>undefined 由于用此定义时他的configurable为true,因此是能够删除对象的 18 Foo.prototype.age = 33 //对于三大特性,我对原型上的属性只作了一个修改的特性,由于原型上定义的方式若是也是对象.属性定义的话,跟对象属性的三大特性同样,在此就不一一举例了 19 console.log(Foo.prototype.age) //=>33 20 </script>
如何用Object.defineProperty自定义属性的特性对象
语法 :blog
Object.defineProperyty(obj,prop,descriptor)ip
obj: 须要定义的对象原型
prop:须要定义 或修改的属性名
descriptor:属性定义或修改的属性描述
该方法容许精确添加或修改对象的属性,正常属性添加经过赋值来建立并显示在属性枚举中(for in 循环或Object.keys()方法),这种 方式添加的属性值可能被改变,也可能会被删除。该方法容许改变这些额外细节默认设置。
configureable:当且仅当这个属性描述符值为true时,该属性可能会改变,也可能会被从相应的对象删除。默认为false.
enumerable:true当且仅当该属性出如今相应的对象枚举属性中。默认为false.
value:与属性有关的值。能够是任何有效的javascript值。默认为undefined.
writable:true当且仅当可能用赋值运算符改变与属性相关的值。默认为false.
第一种方式,当不设定三大属性时?
代码演示以下:
1 <script> 2 //若是用自定义Object.defineProperty方式来自定义属性的话,没有设置三大属性为true时,默认为false,看看在默认状况下会如何 3 function Foo(){} 4 Foo.prototype.age = 22 5 var obj = new Foo() 6 obj.name = "ziksang" 7 Object.defineProperty(obj,"telephone",{ 8 value:15921848427 //这个语句的意思就是在obj对象上建立了一个telephone属性,设定它的值为15921848427,对它的三大属性没有任何设置,此时三大属性为默认false 9 }) 10 console.log(obj.telephone) //由于上面自定义时赋值为15921848427,因此获取值为159.... 11 obj.telephone = 110 //此处我修改其属性值 12 console.log(obj.telephone) //结果输出结果仍是159....由于writable是默认值false,因此是不可修改的 13 for(var p in obj){ //此处输出结果为 name,age 由于用for in枚举的是对象自身属性和原型上的属性,为何没有telephone呢?由于此时obj对象上属性的特性enumerable也是默认false 14 console.log(p) 15 } 16 console.log(Object.keys(obj)) //此处输出结果为name,由于用object.keys枚举的是对象自身的属性 17 delete obj.telephone; //删除telephone属性 18 console.log(obj.telephone) //由于自定义的属性特性默认值为false 因此是不能够删除的 19 20 21 //对象上的原型也能够用此方法定义属性 22 Object.defineProperty(Foo.prototype,"addr",{ 23 value:"上海" //对象原型上自定义一个属性addr 三大特性都为默认值 24 }) 25 console.log(obj.addr); //=>上海 26 for( var k in obj){ //=>name,age 由于上面addr的enumerable默认值是false,因此也是不能够枚举的 27 console.log(k) 28 } 29 delete Foo.prototype.addr //=删除对象原型属性 30 console.log(obj.addr) //=>上海 由于对象原型上属性特性configurable默认为false,因此是不可删除的 31 </script>
第二种方式,当三大属性都为true时,又有什么不一样?
1 <script> 2 //若是用自定义Object.defineProperty方式来自定义属性的话,设置三大属性为true时,看看如下状况又会如何 3 function Foo(){} 4 Foo.prototype.age = 22 5 var obj = new Foo() 6 obj.name = "ziksang" 7 Object.defineProperty(obj,"telephone",{ 8 value:15921848427, 9 writable:true, 10 enumerable:true, 11 configurable:true//这个语句的意思就是在obj对象上建立了一个telephone属性,设定它的值为15921848427,对它的三大属性都设为true 12 }) 13 console.log(obj.telephone) //由于上面自定义时赋值为15921848427,因此获取值为159.... 14 obj.telephone = 110 //此处我修改其属性值 15 console.log(obj.telephone) //结果输出结果仍是110 由于writable是为true ,因此是可修改的 16 for(var p in obj){ //此处输出结果为 name,telephone,age 由于用for in枚举的是对象自身属性和原型上的属性,为何没有telephone呢?由于此时obj对象上属性的特性enumerable也是默认false 17 console.log(p) 18 } 19 console.log(Object.keys(obj)) //此处输出结果为name,telephone由于用object.keys枚举的是对象自身的属性 20 delete obj.telephone; //删除telephone属性 21 console.log(obj.telephone) //由于自定义的属性特configurable为false 因此是能够删除的 22 23 24 //对象上的原型也能够用此方法定义属性 25 Object.defineProperty(Foo.prototype,"addr",{ 26 value:"上海", 27 writable:true, 28 enumerable:true, 29 configurable:true//对象原型上自定义一个属性addr 三大特性都为true 30 }) 31 console.log(obj.addr); //=>上海 32 Foo.prototype.addr = "北京" 33 console.log(obj.addr)//由于writable设为true,因此能够修改原型的属性,因此输出是北京 34 for( var k in obj){ //=>name,age,addr 由于上面addr的enumerable为true,因此也是能够枚举的 35 console.log(k) 36 } 37 delete Foo.prototype.addr //=删除对象原型属性 38 console.log(obj.addr) //=>undefined 由于对象原型上属性特性configurable为true,因此是可删除的 39 </script>
再来深刻了解configurable配置项.
当configurable为flase时 对属性从定义其特性时writable,enumerable的状况如何?
1 <script> 2 //若是用自定义Object.defineProperty方式来自定义属性的话,设置三大属性为true时,看看如下状况又会如何 3 function Foo(){} 4 Foo.prototype.age = 22 5 var obj = new Foo() 6 obj.name = "ziksang" 7 Object.defineProperty(obj,"telephone",{ 8 value:15921848427, 9 writable:false,//若是把三大特性都设为false 10 enumerable:false, 11 configurable:false 12 }) 13 Object.defineProperty(obj,"telephone",{ 14 writable:true, //再把writable 和enumerable再从新定义 15 enumerable:true 16 }) //结果如下都报错,返回空数组,缘由是configurable是一个配置项,当配置项为false时,其它两个特性则不能被从新定义 17 for(var p in obj){ 18 console.log(p) 19 } 20 console.log(Object.keys(obj)) 21 obj.name = "博客园" 22 console.log(obj.name) 23 </script>
当configurable为true时 对属性从定义其特性时writable,enumerable的状况如何?
1 <script> 2 //若是用自定义Object.defineProperty方式来自定义属性的话,设置三大属性为true时,看看如下状况又会如何 3 function Foo(){} 4 Foo.prototype.age = 22 5 var obj = new Foo() 6 obj.name = "ziksang" 7 Object.defineProperty(obj,"telephone",{ 8 value:15921848427, 9 writable:false,//若是把configurable设为true,其它设为false时 10 enumerable:false, 11 configurable:true 12 }) 13 Object.defineProperty(obj,"telephone",{ 14 writable:true, //再把writable 和enumerable再从新定义 15 enumerable:true 16 }) //如下都会返回结果,因可配置的特性configurable设为true,因此其它两个物性均可以重新定义为true 17 for(var p in obj){ //=>name,age ,telephone 18 console.log(p) 19 } 20 console.log(Object.keys(obj)) //=>name,telephone 21 obj.name = "博客园" 22 console.log(obj.name) //=>博客园 23 </script>