注釋:
本文宅自https://segmentfault.com/a/1190000007434923,僅學習方便,沒有任何商業用途
對象是由多個名/值對組成的無序的集合。對象中每個屬性對應任意類型的值。
定義對象可以使用構造函數或字面量的形式:
1 var obj = new Object; //obj = {} 2 obj.name = "張三"; //添加描述 3 obj.say = function(){}; //添加行為
除了以上添加屬性的方式,還可以使用Object.defineProperty定義新屬性或修改原有的屬性
Object.defineProperty()
語法:
1 Object.defineProperty(obj, prop, descriptor)
參數說明:
1 obj:必需。目標對象 2 prop:必需。需定義或修改的屬性的名字 3 descriptor:必需。目標屬性所擁有的特性
返回值:
傳入函數的對象。即第一個參數obj;
針對屬性,我們可以給這個屬性設置一些特性,比如是否只讀不可以寫;是否可以被for..in或Object.keys()遍歷。
給對象的屬性添加特性描述,目前提供兩種形式:數據描述和存取器描述。
數據描述
當修改或定義對象的某個屬性的時候,給這個屬性添加一些特性:
1 var obj = { 2 test:"hello" 3 } 4 //對象已有的屬性添加特性描述 5 Object.defineProperty(obj,"test",{ 6 configurable:true | false, 7 enumerable:true | false, 8 value:任意類型的值, 9 writable:true | false 10 }); 11 //對象新添加的屬性的特性描述 12 Object.defineProperty(obj,"newKey",{ 13 configurable:true | false, 14 enumerable:true | false, 15 value:任意類型的值, 16 writable:true | false 17 });
數據描述中的屬性都是可選的,來看一下設置每一個屬性的作用。
value
屬性對應的值,可以使任意類型的值,默認為undefined
1 var obj = {} 2 //第一種情況:不設置value屬性 3 Object.defineProperty(obj,"newKey",{ 4 5 }); 6 console.log( obj.newKey ); //undefined 7 ------------------------------ 8 //第二種情況:設置value屬性 9 Object.defineProperty(obj,"newKey",{ 10 value:"hello" 11 }); 12 console.log( obj.newKey ); //hello
writable
屬性的值是否可以被重寫。設置為true可以被重寫;設置為false,不能被重寫。默認為false。
1 var obj = {} 2 //第一種情況:writable設置為false,不能重寫。 3 Object.defineProperty(obj,"newKey",{ 4 value:"hello", 5 writable:false 6 }); 7 //更改newKey的值 8 obj.newKey = "change value"; 9 console.log( obj.newKey ); //hello 10 11 //第二種情況:writable設置為true,可以重寫 12 Object.defineProperty(obj,"newKey",{ 13 value:"hello", 14 writable:true 15 }); 16 //更改newKey的值 17 obj.newKey = "change value"; 18 console.log( obj.newKey ); //ch
enumerable
此屬性是否可以被枚舉(使用for...in或Object.keys())。設置為true可以被枚舉;設置為false,不能被枚舉。默認為false。
1 var obj = {} 2 //第一種情況:enumerable設置為false,不能被枚舉。 3 Object.defineProperty(obj,"newKey",{ 4 value:"hello", 5 writable:false, 6 enumerable:false 7 }); 8 9 //枚舉對象的屬性 10 for( var attr in obj ){ 11 console.log( attr ); //console不出來 12 } 13 //第二種情況:enumerable設置為true,可以被枚舉。 14 Object.defineProperty(obj,"newKey",{ 15 value:"hello", 16 writable:false, 17 enumerable:true 18 }); 19 20 //枚舉對象的屬性 21 for( var attr in obj ){ 22 console.log( attr ); //newKey 23 }
configurable
是否可以刪除目標屬性或是否可以再次修改屬性的特性(writable, configurable, enumerable)。設置為true可以被刪除或可以重新設置特性;設置為false,不能被可以被刪除或不可以重新設置特性。默認為false。
這個屬性起到兩個作用:
目標屬性是否可以使用delete刪除
目標屬性是否可以再次設置特性
1 //-----------------測試目標屬性是否能被刪除------------------------ 2 var obj = {} 3 //第一種情況:configurable設置為false,不能被刪除。 4 Object.defineProperty(obj,"newKey",{ 5 value:"hello", 6 writable:false, 7 enumerable:false, 8 configurable:false 9 }); 10 //刪除屬性 11 delete obj.newKey; 12 console.log( obj.newKey ); //hello 13 14 //第二種情況:configurable設置為true,可以被刪除。 15 Object.defineProperty(obj,"newKey",{ 16 value:"hello", 17
除了可以給新定義的屬性設置特性,也可以給已有的屬性設置特性
1 //定義對象的時候添加的屬性,是可刪除、可重寫、可枚舉的。 2 var obj = { 3 test:"hello" 4 } 5 6 //改寫值 7 obj.test = 'change value'; 8 9 console.log( obj.test ); //'change value' 10 11 Object.defineProperty(obj,"test",{ 12 writable:false 13 }) 14 15 16 //再次改寫值 17 obj.test = 'change value again'; 18 19 console.log( obj.test ); //依然是:'change value'
提示:一旦使用Object.defineProperty給對象添加屬性,那么如果不設置屬性的特性,那么configurable、enumerable、writable這些值都為默認的false
1 var obj = {}; 2 //定義的新屬性后,這個屬性的特性中configurable,enumerable,writable都為默認的值false 3 //這就導致了neykey這個是不能重寫、不能枚舉、不能再次設置特性 4 // 5 Object.defineProperty(obj,'newKey',{ 6 7 }); 8 9 //設置值 10 obj.newKey = 'hello'; 11 console.log(obj.newKey); //undefined 12 13 //枚舉 14 for( var attr in obj ){ 15 console.log(attr); 16 }
