Object.defineProperty() 方法會(huì)直接在一個(gè)對(duì)象上定義一個(gè)新屬性,或者修改一個(gè)對(duì)象的現(xiàn)有屬性, 并返回這個(gè)對(duì)象。
語(yǔ)法
Object.defineProperty(obj, prop, descriptor)。
obj:是要在其上定義屬性的對(duì)象(類型object)。
prop:是要定義或修改的屬性的名稱(類型string)。
descriptor:用于定義屬性的性質(zhì)(類型object)。
第三個(gè)參數(shù) descriptor 介紹
descriptor用來(lái)定義(或者說(shuō)描述)屬性的性質(zhì),比如是否可讀寫,是否可刪除,是否可枚舉,以及屬性的性質(zhì)是否可以重新定義等等。
descriptor對(duì)象可以有configurable,enumerable,value,writable四個(gè)屬性;以及get,set兩個(gè)函數(shù)(訪問(wèn)器)。在descriptor對(duì)象中避免(value或writable)和(get或set)同時(shí)出現(xiàn),會(huì)拋出異常。
數(shù)據(jù)型屬性,訪問(wèn)器型屬性
數(shù)據(jù)型屬性:使用configurable,enumerable,writable,value定義的屬性。
訪問(wèn)器型屬性:使用configurable,enumerable,get,set定義的屬性。
如果首次定義屬性且使用Obeject.defineProperty()方法,descriptor對(duì)象沒(méi)有value,writable,get 和 set 任意一個(gè),認(rèn)為其定義的是數(shù)據(jù)型屬性。
configurable
當(dāng)且僅當(dāng) configurable 為 true 時(shí),才可以使用Object.defineProperty()重新定義屬性的 enumerable,writable,get,set,以及configurable自身五個(gè)性質(zhì)。同時(shí)屬性也才能從對(duì)應(yīng)的對(duì)象上被刪除。
有一個(gè)列外,當(dāng)屬性的configurable為false時(shí),如果屬性的writable為true,那么該屬性的writable可以重新定義為false
默認(rèn)值為 false。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的configurable設(shè)置,且descriptor對(duì)象沒(méi)有配置configurable,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的configurable,此時(shí)descriptor對(duì)象缺省configurable,則不設(shè)置保持原值。像 let a={p:10} 或者 let a={};a.p=10 這樣初次定義屬性時(shí),屬性p的configurable為true。
enumerable
表示該屬性是否可枚舉,即是否通過(guò)for-in循環(huán)或Object.keys()返回屬性。
默認(rèn)值為 false。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的enumerable設(shè)置,且descriptor對(duì)象沒(méi)有配置enumerable,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的configurable,此時(shí)descriptor對(duì)象缺省enumberable,則不設(shè)置保持原值。像 let a={p:10} 或者 let a={};a.p=10 這樣初次定義屬性時(shí),屬性p的enumerable為true。
writable
能否修改屬性的值,即常量屬性。
如果屬性從數(shù)據(jù)型,變成訪問(wèn)器型,則writable性質(zhì)失效。
默認(rèn)值為 false。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的writable設(shè)置,且descriptor對(duì)象沒(méi)有配置writable,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的writable,此時(shí)descriptor對(duì)象缺省writable,則不設(shè)置保持原值。像 let a={p:10} 或者 let a={};a.p=10 這樣初次定義屬性時(shí),屬性p的writable為true。
value
該屬性對(duì)應(yīng)的值。
如果屬性從數(shù)據(jù)型,變成訪問(wèn)器型,則value性質(zhì)失效。
默認(rèn)值為 undefined。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的value設(shè)置,且descriptor對(duì)象沒(méi)有配置value,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的value,此時(shí)descriptor對(duì)象缺省value,則不設(shè)置保持原值。
get
get是一個(gè)函數(shù),讀取屬性值時(shí)調(diào)用的函數(shù)。當(dāng)讀取屬性值時(shí),如果get為undefined則返回undefined。如果get為函數(shù),則調(diào)用函數(shù),調(diào)用沒(méi)有參數(shù)傳入,函數(shù)的this與常規(guī)的函數(shù)this一致。get函數(shù)的返回值即為讀取到的值。
如果屬性從訪問(wèn)器型,變成數(shù)據(jù)型,則get性質(zhì)失效
默認(rèn)值 undefined。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的get設(shè)置,且descriptor對(duì)象沒(méi)有配置get,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的get,此時(shí)descriptor對(duì)象缺省get,則不設(shè)置保持原值。
set
set是一個(gè)函數(shù),給屬性賦值時(shí)調(diào)用的函數(shù)。當(dāng)屬性賦值時(shí),如果set為undefined則什么都不做。如果set為函數(shù),則調(diào)用函數(shù),所賦的值傳入函數(shù),函數(shù)的this與常規(guī)的函數(shù)this一致。然后執(zhí)行set函數(shù)。
如果屬性從訪問(wèn)器型,變成數(shù)據(jù)型,則set性質(zhì)失效
默認(rèn)值 undefined。當(dāng)使用Object.defineProperty()定義屬性時(shí),如果屬性當(dāng)前沒(méi)有生效的set設(shè)置,且descriptor對(duì)象沒(méi)有配置set,則取默認(rèn)值。反之如果屬性當(dāng)前已有生效的set,此時(shí)descriptor對(duì)象缺省set,則不設(shè)置保持原值。
對(duì)象字面量定義屬性
像 let a={p:10}定義對(duì)象, 或者 let a={};a.p=10 這樣初次定義屬性時(shí),屬性的類型是數(shù)據(jù)型,且configurable為true,enumerable為true,writable為true