如何自定義屬性的特性? 用對象.屬性的特性和自定義的屬性的特性有什麼區別? 它的四大特性 writable enumerable configable 有什麼區別? 先預習一個用對象.屬性定義 ,屬性的四大特性是以什麼方式呈現的。 這時個屬性的三大特性預設值都為true。 代碼演示: 1 <scri
如何自定義屬性的特性?
用對象.屬性的特性和自定義的屬性的特性有什麼區別?
它的四大特性 writable enumerable configable 有什麼區別?
先預習一個用對象.屬性定義 ,屬性的四大特性是以什麼方式呈現的。
這時個屬性的三大特性預設值都為true。
代碼演示:
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自定義屬性的特性
語法 :
Object.defineProperyty(obj,prop,descriptor)
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>