一、對(duì)象
對(duì)象是JavaScript的基本數(shù)據(jù)類型,對(duì)象可以看作屬性的無(wú)序集合,每個(gè)屬性都是一個(gè)名\值對(duì),屬性是一個(gè)字符串,因此可以把對(duì)象看做對(duì)象到值得映射。JavaScript中的對(duì)象可以從一個(gè)稱之為原型的對(duì)象上繼承屬性,這種原型式繼承JavaScript的核心特性。
JavaScript中對(duì)象可以分為三類,內(nèi)置對(duì)象、宿主對(duì)象、自定義對(duì)象;
內(nèi)置對(duì)象:是有ECMAScript規(guī)范定義的對(duì)象或類,例如數(shù)組,函數(shù),日期對(duì)象。
宿主對(duì)象:宿主對(duì)象是有JavaScript解釋器所定義的宿主環(huán)境(比如Web瀏覽器)所定義的 。
自定義對(duì)象:是由運(yùn)行的JavaScript代碼創(chuàng)建的對(duì)象。
屬性可以分為自有屬性和繼承屬性。
自有屬性:直接在對(duì)象中定義的屬性。
繼承屬性:在對(duì)象的原型中定義的屬性。
二、對(duì)象的原型
每個(gè)JavaScript對(duì)象都和另外一個(gè)對(duì)象關(guān)聯(lián),這個(gè)被關(guān)聯(lián)的對(duì)象就是對(duì)象的原型。對(duì)象可以從原型上繼承屬性。
對(duì)象字面量創(chuàng)建的對(duì)象的原型是Object.prototype。
通過(guò)new關(guān)鍵字創(chuàng)建的對(duì)象的原型是構(gòu)造函數(shù).prototype。例如new Array()創(chuàng)建的對(duì)象時(shí)原型是Array.prototype.
通過(guò)Object.create()方法創(chuàng)建的對(duì)象的原型是Object.create()的第一個(gè)參數(shù)。
三、創(chuàng)建對(duì)象
1、對(duì)象直接量
創(chuàng)建對(duì)象最簡(jiǎn)單的方式就是使用對(duì)象直接量,對(duì)象直接量是由若干名/值對(duì)組成的映射表。名/值對(duì)中間用冒號(hào)分割,名/值對(duì)之間用逗號(hào)分割,整個(gè)映射表用花括號(hào)括起來(lái)。屬性名可以是JavaScript標(biāo)識(shí)符也可以是字符串直接量(包括空字符串),屬性值可以是任意類型的JavaScript表達(dá)式。對(duì)象直接量是一個(gè)JavaScript表達(dá)式,表達(dá)式的每次運(yùn)算都會(huì)創(chuàng)建一個(gè)新的對(duì)象。
1 var obj={ 2 x:1, 3 'y':2 4 } 5 var o={};//創(chuàng)建一個(gè)空對(duì)象 6 var ob={ 7 x:1, 8 //構(gòu)造器屬性 9 set y(value){10 this.x=2;11 },12 get y(){13 return 10;;14 }15 }
2、new關(guān)鍵字
new關(guān)鍵字用來(lái)創(chuàng)建一個(gè)對(duì)象,后面跟上一個(gè)構(gòu)造函數(shù)。
1 var o=new Object();//創(chuàng)建一個(gè)空對(duì)象2 var ob=new Array();創(chuàng)建一個(gè)空對(duì)象3 var obj=new RegExp('js');//創(chuàng)建一個(gè)正則表達(dá)式對(duì)象
3、Object.create()
Object.create()可以接受兩個(gè)參數(shù),第一個(gè)參數(shù)是新創(chuàng)建對(duì)象的原型,第二個(gè)參數(shù)是可選的。這些屬性對(duì)應(yīng)Object.defineProperties()
的第二個(gè)參數(shù)。
1 var o; 2 o=Object.create(null);//創(chuàng)建一個(gè)原型為null的空對(duì)象。 3 o=Object.create(Object.prototype);//和var={}一樣的空對(duì)象 4 o=Object.create(Object.prototype,{ 5 foo:{ 6 value:10, 7 writable:true, 8 enumerable:true, 9 configurable:false10 },11 bar:{12 configurable:true,13 enumerable:true,14 set:function(value){15 console.log(value);16 },17 get:function(){18 return 10;19 }20 21 }22 });23 console.log(o.foo);//1024 console.log(o.bar);//10
四、訪問(wèn)和設(shè)置對(duì)象屬性
訪問(wèn)和設(shè)置對(duì)象的屬性有兩種方法,可以通過(guò)點(diǎn)(.)運(yùn)算符和([])運(yùn)算符來(lái)獲取和設(shè)置對(duì)象的屬性。運(yùn)算符的左邊應(yīng)該是一個(gè)表達(dá)式,返回一個(gè)對(duì)象,點(diǎn)運(yùn)算符的右邊是一個(gè)以屬性命名的標(biāo)識(shí)符。([])內(nèi)必須是計(jì)算結(jié)果為字符串的表達(dá)式。
1 var o;2 o=Object.create(Object.prototype);//和var={}一樣的空對(duì)象3 //設(shè)置屬性4 o.bar=10;5 o['foo']=100;6 //訪問(wèn)屬性7 console.log(o.foo);//1008 console.log(o['bar']);//10
通過(guò)([])運(yùn)算符和字符串的方式訪問(wèn)屬性看起來(lái)更像一個(gè)數(shù)組,只不過(guò)這種數(shù)組通過(guò)的是字符串索引而不是數(shù)字。這種數(shù)組成為關(guān)聯(lián)數(shù)組。通過(guò)([])方式訪問(wèn)對(duì)象的屬性可以對(duì)字符串進(jìn)行修改,而(.)的方式不能修改標(biāo)識(shí)符。o['arr'+i]
1 function add(obj,name,value){2 obj[name]=value;3 }
運(yùn)行函數(shù)之前,我們無(wú)法知道要給對(duì)象添加什么屬性。所以只能用([])方式。
可以通過(guò)for/in循環(huán)遍歷對(duì)象。
1 var o={x:1,y:0}2 for(var p in o){3 console.log(o[p]);// 1 04 }
自有屬性和繼承屬性
對(duì)象的屬性有自有屬性和繼承屬性,當(dāng)我們?cè)L問(wèn)一個(gè)對(duì)象的某個(gè)屬性x時(shí),先要在查找對(duì)象上是否存在x屬性,當(dāng)對(duì)象上不存在x屬性時(shí),會(huì)到對(duì)象的原型上查找,如果對(duì)象的原型上不存在x屬性,則繼續(xù)在這個(gè)對(duì)象的原型上找,直到找到在對(duì)象的原型上找到x或者找到一個(gè)原型是null的對(duì)象。
1 var o={x:1,y:10}2 var obj=Object.create(o);3 obj.z=11;4 console.log(obj.z);//11 對(duì)象的自有屬性5 console.log(obj.x);//1 對(duì)象的原型屬性6 console.log(obj.toString()); //對(duì)象的原型的原型Object.prototype的屬性
如果給對(duì)象屬性x賦值,對(duì)象如果不存在這個(gè)屬性,那么對(duì)象會(huì)添加一個(gè)屬性x,如果對(duì)象存在屬性x,那么會(huì)修改這個(gè)屬性的值,如果對(duì)象沒(méi)有這個(gè)屬性但是對(duì)象的原型有這個(gè)屬性x,那么會(huì)在對(duì)象上添加這個(gè)屬性,訪問(wèn)對(duì)象的x屬性將不會(huì)訪問(wèn)到對(duì)象的原型上的x屬性。
1 var o={x:1,y:10} 2 var obj=Object.create(o); 3 //對(duì)象上沒(méi)有的屬性賦值,新建一個(gè)屬性z 4 obj.z=11; 5 //給對(duì)象的已有屬性賦值,修改屬性值。 6 obj.z=1; 7 //給對(duì)象上不存在但原型上存在的屬性賦值,對(duì)象會(huì)添加這個(gè)屬性 8 obj.x=2; 9 console.log(obj.x)//210 console.log(o.x)//1
對(duì)象的屬性賦值操作會(huì)首先檢查原型鏈,以此判斷是否允許賦值。如果對(duì)象繼承了一個(gè)只讀屬性,那么對(duì)這個(gè)屬性賦值是不允許的。
1 var o={}; 2 Object.defineProperty(o, "key", { 3 enumerable: false, 4 configurable: false, 5 writable: false, 6 value: "static" 7 }); 8 var obj=Object.create(o); 9 console.log(obj.key);//"static"10 obj.key=3;11 console.log(obj.key);//"static"
對(duì)象的賦值總是在原始對(duì)象上操作的,不會(huì)影響原型對(duì)象。對(duì)象的繼承只有在查詢是才能體會(huì)到。對(duì)象的賦值會(huì)創(chuàng)建一個(gè)屬性或者修改一個(gè)屬性,但是有一個(gè)例外,如果對(duì)象繼承的是一個(gè)構(gòu)造器屬性x,那么給對(duì)象對(duì)象賦值不會(huì)創(chuàng)建x雙屬性,只是調(diào)用setter方法。如果調(diào)用setter方法時(shí)定義了屬性,那么這個(gè)屬性只是針對(duì)對(duì)象o,與原型無(wú)關(guān)。
屬性的訪問(wèn)出錯(cuò)
訪問(wèn)對(duì)象不存在的屬性不會(huì)出錯(cuò),會(huì)返回undefined。
如果訪問(wèn)不存在對(duì)象的屬性時(shí)會(huì)出錯(cuò),null和undefined沒(méi)有屬性,訪問(wèn)它們的屬性會(huì)出錯(cuò)。
下面提供了兩種防止出錯(cuò)的方法。
var len;
if(book){
if(book.subtitle) len=book.subtitle.length;
}
也可以寫成
var len=book&&book.subtitle&&book.subtitle.length;
設(shè)置屬性出錯(cuò)
給null和undefined屬性賦值會(huì)出錯(cuò)。給其他對(duì)象設(shè)置屬性有可能失敗,但是不會(huì)出錯(cuò)。
下面是對(duì)象設(shè)置值失敗的情況;
1、對(duì)象的屬性p是只讀的。
2、對(duì)象的屬性p是繼承屬性,且是可讀的。
3、對(duì)象沒(méi)有屬性p,且沒(méi)有繼承構(gòu)造器屬性setter,則一定可以設(shè)置p屬性,但是如果對(duì)象是不可以擴(kuò)展的,則不能給對(duì)象設(shè)置屬性。
五、刪除屬性
可以使用delete運(yùn)算符刪除對(duì)象的屬性,delete運(yùn)算符的操作數(shù)應(yīng)當(dāng)是一個(gè)屬性訪問(wèn)表達(dá)式。
delete運(yùn)算只是斷開屬性和宿主對(duì)象的聯(lián)系。
1 var obj={2 x:{y:1}3 }4 var o=obj.x;5 delete obj.x;6 console.log(o.y);//1
delete運(yùn)算符只能刪除對(duì)象的自有屬性,而不能刪除對(duì)象的繼承屬性。
detete刪除成功或者沒(méi)有副作用(刪除對(duì)象不存在的屬性)會(huì)返回true,刪除對(duì)象的不可配置屬性會(huì)返回false.
1 var o={};2 Object.defineProperty(o,'x',{value:1,configurable:false})3 console.log(delete o.x);//false
六、檢測(cè)屬性
方法一:in運(yùn)算符,in運(yùn)算符的左側(cè)是屬性(字符串),右側(cè)是對(duì)象。如果對(duì)象的自有屬性或者繼承屬性(與屬性的可枚舉性無(wú)關(guān))包含這個(gè)屬性,則返回true。
1 var o={ 2 set y(value){ 3 console.log(value); 4 }, 5 get y(){ 6 return 120; 7 } 8 }; 9 Object.defineProperty(o,'x',{value:1,enumerable:true})10 console.log('x' in o);//true11 console.log("toString" in o);//true12 console.log('y' in o);
方法二:hasOwnProperty(),這個(gè)方法可以用來(lái)檢測(cè)一個(gè)對(duì)象是否含有特定的自身屬性;和 in
運(yùn)算符不同,該方法會(huì)忽略掉那些從原型鏈上繼承到的屬性。
1 var o={ 2 set y(value){ 3 console.log(value); 4 }, 5 get y(){ 6 return 120; 7 } 8 }; 9 Object.defineProperty(o,'x',{value:1,enumerable:true})10 console.log(o.hasOwnProperty('x'));//true11 console.log(o.hasOwnProperty('toString'));//false12 console.log(o.hasOwnProperty('y'));//true
方法三:propertyIsEnumerable(),只有對(duì)象時(shí)自身的且可以枚舉才返回true.
1 var o={ 2 set y(value){ 3 console.log(value); 4 }, 5 get y(){ 6 return 120; 7 } 8 }; 9 Object.defineProperty(o,'x',{value:1,enumerable:false})10 console.log(o.propertyIsEnumerable('x'));//false不可枚舉11 console.log(o.propertyIsEnumerable('toString'));//false 不是自身屬性12 console.log(o.propertyIsEnumerable('y'));//true
方法四:同!==運(yùn)算符判斷,不過(guò)當(dāng)對(duì)象的屬性值為undefined的時(shí)候不能判斷。
1 var o={ 2 set y(value){ 3 console.log(value); 4 }, 5 get y(){ 6 return undefined; 7 } 8 }; 9 Object.defineProperty(o,'x',{value:1,enumerable:false})10 console.log(o.x!==undefined);//true11 console.log(o.y!==undefined);//false 屬性存在(特殊情況)12 console.log(o.toString!==undefined)//true
七、枚舉屬性
方法一:for/in循環(huán) 遍歷對(duì)象中的所有可枚舉屬性(包括自有屬性和繼承屬性)
1 var o={ 2 z:10, 3 set y(value){ 4 console.log(value); 5 }, 6 get y(){ 7 return 10; 8 } 9 };10 Object.defineProperty(o,'x',{value:1,enumerable:false});11 function extend(p,o){12 //對(duì)于構(gòu)造器屬性,只會(huì)簡(jiǎn)單的賦值屬性的值。 13 for(var s in o){14 p[s]=o[s];15 }16 return p;17 }18 var p={};19 var p=extend(p,o);20 console.log(p);//{x:10,y:10}
方法二:Object.keys() 返回一個(gè)數(shù)組,數(shù)組的元素由對(duì)象自身的可枚舉屬性組成。
1 var o={ 2 z:10, 3 set y(value){ 4 console.log(value); 5 }, 6 get y(){ 7 return 10; 8 } 9 };10 Object.defineProperty(o,'x',{value:1,enumerable:false});11 console.log(Object.keys(o));//['x','y']
方法三:Object.getOwnPropertyNames() 返回一個(gè)數(shù)組,數(shù)組的元素由對(duì)象的自有屬性組成。
1 var o={ 2 z:10, 3 set y(value){ 4 console.log(value); 5 }, 6 get y(){ 7 return 10; 8 } 9 };10 Object.defineProperty(o,'x',{value:1,enumerable:false});11 console.log(Object.getOwnPropertyNames(o));//['x','y','z']
八、存取器屬性
對(duì)象的屬性由名/值和一對(duì)特性組成,es5中可以用一個(gè)或兩個(gè)方法代替,這個(gè)就是setter和getter方法。由setter和getter定義的屬性叫做構(gòu)造器屬性。它不同于數(shù)據(jù)屬性,數(shù)據(jù)屬性只是一個(gè)簡(jiǎn)單的值。
查詢對(duì)象的存取器屬性的值時(shí),調(diào)用getter(無(wú)參數(shù)),設(shè)置對(duì)象的存取器屬性的值時(shí),調(diào)用對(duì)象的setter方法,將賦值表達(dá)式右側(cè)的值當(dāng)做參數(shù)傳入setter方法。setter方法的返回值可以忽略。
和數(shù)據(jù)屬性不同,存取器屬性不具有可寫性,如果屬性同時(shí)具有setter和getter方法,那么這個(gè)對(duì)象是可讀寫的,如果屬性只有g(shù)etter方法,那么屬性是只讀的,如果對(duì)象只有setter方法,那么對(duì)象是只寫的,讀取對(duì)象的屬性總是返回undefined。
存取器屬性定義為一個(gè)或者兩個(gè)和屬性同名的函數(shù),函數(shù)的關(guān)鍵字用get或者set代替,屬性名和函數(shù)體之間沒(méi)有冒號(hào),函數(shù)的結(jié)束和下一個(gè)方法或者屬性的開始之間用逗號(hào)隔開。
存取器的函數(shù)可以看作對(duì)象的方法,函數(shù)體內(nèi)可以使用this指向當(dāng)前對(duì)象。存取器屬性是可以繼承的 。
九、屬性的特性
為了實(shí)現(xiàn)對(duì)象屬性的設(shè)置和查詢,es5中定義了一個(gè)屬性描述符對(duì)象,這個(gè)對(duì)象包含了屬性的四個(gè)特性,
對(duì)象的存取器屬性的四個(gè)特性:get,set,enumerable,configurable,
數(shù)據(jù)屬性的四個(gè)特性:value,writable,enumerable,configurable
configurable
true
當(dāng)且僅當(dāng)該屬性描述符的類型可以被改變并且該屬性可以從對(duì)應(yīng)對(duì)象中刪除。false
enumerable
true
當(dāng)且僅當(dāng)在枚舉相應(yīng)對(duì)象上的屬性時(shí)該屬性顯現(xiàn)。false
value
undefined
. writable
true
當(dāng)且僅當(dāng)與該屬性相關(guān)聯(lián)的值可以用assignment operator改變時(shí)。false
get
undefined
。函數(shù)返回值將被用作屬性的值。undefined
set
undefined
。函數(shù)將僅接受參數(shù)賦值給該屬性的新值。undefined
Object.getOwnPropertyDescriptor()
方法返回指定對(duì)象上一個(gè)自有屬性對(duì)應(yīng)的屬性描述符。(自有屬性指的是直接賦予該對(duì)象的屬性,不需要從原型鏈上進(jìn)行查找的屬性)
Object.getOwnPropertyDescriptors()
方法用來(lái)獲取一個(gè)對(duì)象的所有自身屬性的描述符。
1 var o = { 2 z: 10, 3 set y(value) { 4 console.log(value); 5 }, 6 get y() { 7 return 10; 8 } 9 };10 console.log(Object.getOwnPropertyDescriptor(o, 'z'));11 /*{ value: 10,12 writable: true,13 enumerable: true,14 configurable: true 15 }*/16 console.log(Object.getOwnPropertyDescriptors(o));17 /*18 { z:19 { value: 10,20 writable: true,21 enumerable: true,22 configurable: true },23 y:24 { get: [Function: get y],25 set: [Function: set y],26 enumerable: true,27 configurable: true } }28 */
設(shè)置或者新建對(duì)象的特性
Object.defineProperty()
方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象。
Object.defineProperties()
方法直接在一個(gè)對(duì)象上定義新的屬性或修改現(xiàn)有屬性,并返回該對(duì)象。
var obj = {};Object.defineProperties(obj, { 'property1': { value: true, writable: true }, 'property2': { value: 'Hello', writable: false }});var descriptor = Object.create(null); // 沒(méi)有繼承的屬性// 默認(rèn)沒(méi)有 enumerable,沒(méi)有 configurable,沒(méi)有 writabledescriptor.value = 'static';Object.defineProperty(obj, 'key', descriptor);// 顯式Object.defineProperty(obj, "key", { enumerable: false, configurable: false, writable: false, value: "static"});//添加構(gòu)造器屬性Object.defineProperty(o, "b", { get : function(){ return bValue; }, set : function(newValue){ bValue = newValue; }, enumerable : true, configurable : true});
對(duì)于新創(chuàng)建的屬性,默認(rèn)值為false或者undefined,對(duì)于修改的屬性,默認(rèn)的屬性值沒(méi)有任何改變。
Object.defineProperty()和
Object.defineProperties()違反規(guī)則的使用將會(huì)報(bào)錯(cuò)。
1、對(duì)象不可擴(kuò)展,可以編輯對(duì)象的屬性,但是不能給對(duì)象添加屬性。
2、對(duì)象的屬性是不可以配置的,不能修改它的可配置性和可枚舉性。
3、對(duì)象的屬性是存取器屬性且不可配置的,不可以修改其getter和setter方法,也不能將他轉(zhuǎn)換成數(shù)據(jù)屬性。
4、對(duì)象的屬性時(shí)數(shù)據(jù)屬性且不可配置的,不能將其轉(zhuǎn)化成存取器屬性。
5、如果數(shù)據(jù)屬性是不可配置的,不能將他的可寫性從false轉(zhuǎn)化為true,但是可以把它從true轉(zhuǎn)化成false.
6、如果數(shù)據(jù)屬性是不可配置不可寫的,不能修改它的值,但是可配置不可寫的屬性是可以修改他的值得。
1 //給Obejcet.Prototype對(duì)象添加自定義的繼承函數(shù) 2 //參數(shù)對(duì)象的屬性和屬性描述符都會(huì)被復(fù)制。 3 //如果對(duì)象中存在同名屬性,則忽略。 4 Object.defineProperty(Object.prototype, 'extend', { 5 configurable: false, 6 writable: false, 7 enumerable: false, 8 value: function (o) { 9 var arr = Object.getOwnPropertyNames(o);10 var desc;11 for (var i = 0; i < arr.length; i++) {12 if (arr[i] in this) continue;13 desc = Object.getOwnPropertyDescriptor(o, arr[i]);14 Object.defineProperty(this, arr[i], desc);15 }16 }17 })18 var o = { x: 1 };19 Object.defineProperty(o, 'key', {20 value: 'static',21 writable: true,22 enumerable: false23 });24 var p = {};25 p.extend(o);26 console.log(Object.getOwnPropertyDescriptor(p,"key"));27 28 /*{ value: 'static',29 writable: true,30 enumerable: false,31 configurable: false }*/
十、對(duì)象的三個(gè)屬性
每一個(gè)對(duì)象都有的原型、類和可擴(kuò)展性。
對(duì)象的原型
對(duì)象的原型屬性是用來(lái)繼承屬性的,原型對(duì)象在對(duì)象創(chuàng)建之前就設(shè)置好的。
Object.getPrototypeOf()
方法返回指定對(duì)象的原型。也可以通過(guò)對(duì)象的__proto__屬性訪問(wèn)對(duì)象的原型。通過(guò)構(gòu)造函數(shù)創(chuàng)建的對(duì)象和對(duì)象字面量創(chuàng)建的對(duì)象可以用對(duì)象的構(gòu)造器constructor.prototype屬性訪問(wèn)對(duì)象的原型。
1 function X(){2 this.y=10,3 this.z=11;4 }5 X.prototype.a=111;6 var x=new X();7 console.log(Object.getPrototypeOf(x));//X.prototype8 console.log(x.__proto__);//X.prototype9 console.log(x.constructor.prototype);//X.prototype
通過(guò)對(duì)象的構(gòu)造函數(shù)創(chuàng)建的對(duì)象,對(duì)象的原型上的constructort指向構(gòu)造函數(shù)。
檢測(cè)是不是對(duì)象的原型:isPrototypeOf();
1 function X(){2 this.y=10,3 this.z=11;4 }5 X.prototype.a=111;6 var x=new X();7 console.log(X.prototype.isPrototypeOf(x));//true
對(duì)象的類屬性
對(duì)象的類屬性是一個(gè)字符串,用來(lái)表示對(duì)象的類型。只能通過(guò)toString()方法簡(jiǎn)單的獲取,但是很多對(duì)象都重寫了toString()方法。可以用如下的工具函數(shù)獲得對(duì)象的類屬性。
8 function classof(o){ 9 if(o===null) return "null";10 if(o===undefined) return "undefined";11 return Object.prototype.toString.call(o).slice(8,-1);12 }13 console.log(classof(""));//'String'
對(duì)象的可擴(kuò)展性
對(duì)象的可擴(kuò)展性表明是否可以給對(duì)象添加屬性。所有的內(nèi)置對(duì)象都是可擴(kuò)展的。Object.preventExtensions()可以將對(duì)象變成不可擴(kuò)展的,這個(gè)過(guò)程是不可逆的。把對(duì)象轉(zhuǎn)化成不可擴(kuò)展的值影響對(duì)象本身,對(duì)象的原型依舊是可以擴(kuò)展的,可其添加的方法對(duì)象會(huì)繼承。
Object.isExtensible()
方法判斷一個(gè)對(duì)象是否是可擴(kuò)展的(是否可以在它上面添加新的屬性)。
Object.preventExtensions()
方法讓一個(gè)對(duì)象變的不可擴(kuò)展,也就是永遠(yuǎn)不能再添加新的屬性。
1 function X(){ 2 this.y=10, 3 this.z=11; 4 } 5 var x=new X(); 6 //判斷對(duì)象是不可以擴(kuò)展 7 console.log(Object.isExtensible(x));//true 8 //將對(duì)象轉(zhuǎn)化成不可擴(kuò)展的 9 Object.preventExtensions(x);10 //給對(duì)象添加屬性11 x.b=11;12 console.log(x.b);//undefined13 //給對(duì)象的原型添加方法14 X.prototype.a=111;15 console.log(x.a);//111
Object.seal()
方法可以讓一個(gè)對(duì)象密封,并返回被密封后的對(duì)象。密封對(duì)象將會(huì)阻止向?qū)ο筇砑有碌膶傩裕⑶視?huì)將所有已有屬性的可配置性(configurable)置為不可配置(false),即不可修改屬性的描述或刪除屬性。但是可寫性描述(writable)為可寫(true)的屬性的值仍然可以被修改。不可逆的過(guò)程
Object.isSealed()
方法判斷一個(gè)對(duì)象是否被密封。
Object.freeze()
方法可以凍結(jié)一個(gè)對(duì)象,凍結(jié)指的是不能向這個(gè)對(duì)象添加新的屬性,不能修改其已有屬性的值,不能刪除已有屬性,以及不能修改該對(duì)象已有屬性的可枚舉性、可配置性、可寫性。也就是說(shuō),這個(gè)對(duì)象永遠(yuǎn)是不可變的。該方法返回被凍結(jié)的對(duì)象。不可逆的過(guò)程。如果對(duì)象有setter方法,還可以給對(duì)象賦值。
Object.isFrozen()
方法判斷一個(gè)對(duì)象是否被凍結(jié)。
十一、對(duì)象的序列化
對(duì)象的序列化是將對(duì)象轉(zhuǎn)化成字符串。es5中用JSON.stringify()和JSON.parse()方法序列化和還原對(duì)象。JSON.stringify()只能序列化對(duì)象的可枚舉屬性,不可以枚舉的屬性在序列化時(shí)會(huì)被省略。可以序列化對(duì)象、數(shù)組、字符串、無(wú)窮大、true、false和null.函數(shù)、Error對(duì)象、正則和undefined不能序列化。NaN、無(wú)窮大序列化的結(jié)果是null.日期對(duì)象序列化是一個(gè)日期字符串,無(wú)法還原成對(duì)象。
1 var o={ 2 now:new Date(), 3 x:null, 4 y:Infinity, 5 }; 6 Object.defineProperty(o,'z',{ 7 enumerable:false, 8 }); 9 //序列化對(duì)象10 var s=JSON.stringify(o);11 console.log(s);//'{"now":"2018-03-12T19:34:38.685Z","x":null,"y":null}'12 //反序列化13 console.log(JSON.parse(s));//{ now: '2018-03-12T19:34:38.685Z', x: null, y: null }
十二、原型上的方法
toString();對(duì)象轉(zhuǎn)化成字符串時(shí)調(diào)用。
toLocaleString()返回對(duì)象的本地化字符串。默認(rèn)回調(diào)用toString();Date()和Number()對(duì)象的toLocaleString()做了定制,可以轉(zhuǎn)換成本地化轉(zhuǎn)化。
toJSON()。JSON.Stringify()會(huì)調(diào)用這個(gè)方法。
valueOf()對(duì)象類型轉(zhuǎn)化時(shí)調(diào)用。日期對(duì)象的valueOf()做了定制。返回1970.1.1到現(xiàn)在的毫秒數(shù)。
聯(lián)系客服