1. 程式人生 > >Object.defineProperty的理解

Object.defineProperty的理解

Hellow 大家好 今天我來給各位小夥伴講一下vue實現資料變化監聽的方法 Object.defineProperty (若出現錯誤可在下方給小蘇留言喔)

1.首先我們來看一下Object.defineProperty接收的引數

Object.defineProperty(obj,prop,descriptor)
obj→相當於傳入的一個物件
prop→相當於是要定義或修改的屬性的名稱。
descriptor→將被定義或修改的屬性描述符。

2.descriptor屬性描述符

資料描述符和存取描述符均具有以下可選鍵值:

value
該屬性對應的值。可以是任何有效的JavaScript值(數值,物件,函式等)。預設為undefind

configurable
當configurable設定為True時該屬性描述符才能夠改變,同時該屬性也能從對應的物件上被刪除。預設為false

writable
當改屬性設定為true時,value才能被賦值運算子改變	。預設為false。

enumerable
當且僅當該屬性的enumerable為true時,該屬性才能夠出現在物件的列舉屬性中。預設為 false。

存取描述符同時具有以下可選鍵值:

get
一個給屬性提供getter的方法,如果沒有getter則為undefind。當訪問prop屬性時,該方法就會立即執行,方法執行沒有傳入引數時,但是會傳入this物件(這裡的this並不一定是定義該屬性的物件)
預設為:undefind

set
一個給屬性提供setter的方法,如果沒有setter則為undefind。當監聽到prop屬性修改時,該方法就會立即執行,該方法接收一個引數為修改後屬性的新值,。
預設為: undefind

例子:

=============程式碼我會在一一解答================

var data = {
	name: '小蘇',
	age: 22,
	sex: '男'
}
//我們使用forEach將data的屬性進行遍歷出來
Object.keys(data).forEach(function(key){
	Object.defineProperty(data,key,{
		enumerable: true,		//當且僅當該屬性的enumerable為true時,該屬性才能夠出現在物件的列舉屬性中。預設為 false。
		configurable: false,		//當configurable設定為True時該屬性描述符才能夠改變,同時該屬性也能從對應的物件上被刪除。預設為false
		get: function(){
			console.log('獲取到屬性值為:'+this.value)
			return this.value
		},
		set: function(newValue){
			console.log(key+'屬性值發生了變化,變化後為:'+newValue);
			this.value = newValue;
		}
	})
})

在這裡插入圖片描述

當我們執行之一段程式碼,我們去獲取data.name屬性的值的時候我們會發現,為什麼獲取的值是undefined呢? 在這裡插入圖片描述 接下來我們就再通過下面一段程式碼去看看它是為什麼回這樣 在這裡插入圖片描述 在這裡插入圖片描述 此時我們又能獲取到了data.name屬性的值,但是此時獲取到的屬性的值卻是setter改變之後的值,由此我們不難看出,因為一開始我們就進入到了getter但是此時的this.value是沒有值的,因為返回給我們的當然也就是undefinde了。而後面我們通過data.name = 'sd’呼叫了setter的方法此時 this.value的值也被賦予了newValue所以此時getter方法呼叫時就會返回this.value的值,但是這樣做還是會有Bug,因為當你再獲取data的其他屬性時你會發現返回的永遠都是那個newValue;

那麼我們要怎麼去解決這個問題呢 方法很簡單,我們可以用閉包的方法去實現就可以了。 在這裡插入圖片描述 在這裡插入圖片描述

writable使用案例: 當設定為false時此時控制檯就會報錯

configurable使用案例: 當設定configurable為false時,此時控制檯就會報錯了,因為你不能刪除設定了不能刪除當前這個屬性 在這裡插入圖片描述 在這裡插入圖片描述

當一個描述符不具有value,writable,get,set任意一個關鍵字,那麼它將被認為是一個數據描述符。如果一個描述符同時有(value或writable)和(get或set)關鍵字,將會產生一個異常。

!!!!當描述符同時有value或writable 和 get或set關鍵字時,將會產生一個異常 當描述符同時有value或writable 和 get或set關鍵字時,將會產生一個異常 此時我們就會在控制檯看見報錯 控制檯報錯描述

當我們翻譯這段報錯的時候就可以看到:

型別錯誤:屬性描述符無效。不能同時指定訪問器和一個value或可寫屬性#

更多精彩的部落格請關注小蘇的CSDN賬號喔也可以小蘇的 扣扣: 1092453305 來討論更多的學習問題