三分鐘搞懂js屬性描述符之基礎知識

前言:這年頭全部用過vue的人都知道get,set,Object.defineProperty,可聽到屬性描述符卻有點懵。另外實際使用的場景有哪些,又有哪些坑可能不少人並不清楚,所以打算分兩篇文章,一篇講基礎知識,另外一篇講實際應用中的坑。vue

什麼是屬性描述符對象

下面這麼個對象就是完整的屬性描述符。json

{
    configurable: false,
    enumberable: false,
    value: 'value',
    writable: false,
    get: function() {
        console.log('get')
    },
    set: function(val) {
        console.log('set')
    }
}

固然正常狀況下你不會看到完整的屬性描述符。它的每一個屬性都是可選的。當一個屬性描述符沒有沒有get和set時,它是個數據描述符。當它沒有value和writable時,它是個存取描述符。若是一個描述符同時有(value或writable)和(get或set)關鍵字,將會產生一個異常。函數

描述符可同時具備的鍵值this

PropertyDescriptor configurable enumerable value writable get set
數據描述符 Yes Yes Yes Yes No No
存取描述符 Yes Yes No No Yes Yes

每種屬性的含義

configurable
當且僅當該屬性的 configurable 爲 true 時,該屬性描述符纔可以被改變,同時該屬性也能從對應的對象上被刪除。spa

enumerable
當且僅當該屬性的enumerabletrue時,該屬性纔可以出如今對象的枚舉屬性中。3d

value
該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。code

writable
當且僅當該屬性的writabletrue時,value才能被賦值運算符改變。對象

get
一個給屬性提供 getter 的方法,若是沒有 getter 則爲 undefined。當訪問該屬性時,該方法會被執行,方法執行時沒有參數傳入,可是會傳入this對象(因爲繼承關係,這裏的this並不必定是定義該屬性的對象)。blog

set
一個給屬性提供 setter 的方法,若是沒有 setter 則爲 undefined。當屬性值修改時,觸發執行該方法。該方法將接受惟一參數,即該屬性新的參數值。繼承

關於默認值

以上的定義和解釋來自於mdn,可是刪除了默認值的說明。默認值分兩種語境,一個是我沒有設置屬性描述符時,就去取它;另外一種是我設置屬性描述符,可是我省略了部分屬性。mdn上的默認值是後者

獲取屬性描述符

Object.getOwnPropertyDescriptorObject.getOwnPropertyDescriptors,二者模式差很少,懂一個就懂另外一個了。
image.png
可見其中writable、enumerable、configurable默認是true

設置屬性描述符

Object.definePropertyObject.defineProperties,一樣一個就懂另外一個了。
咱們分別設置get和value,而後再獲取屬性描述符看看區別
get:
image.png
value:
image.png
能夠看到,當我設置了屬性描述符後writable、enumerable、configurable默認是false。
enumerable爲false時
而且細心的同窗發現了,對象的這個屬性名的顏色有點不同。不過此時咱們先忽略這個顏色的區別。
image.png
咱們將它轉爲json字符串,發現沒有age和address。嗯,這就是由於enumerable設置成了false,使得它被轉爲字符串的過程當中沒法遍歷到這兩個屬性。咱們能夠將enumerable設置成true再試一下。
image.png
configurable爲false時
image.png
由於缺省的configurable默認爲false,當咱們再次設置時就報錯了。此時就陷入了無解的狀態,所以咱們平時開發中須要設置屬性描述符時,最好不要缺省enumerable和configurable
咱們從頭來一次:
image.png

關於屬性描述符,我想你們應該都有一個大體的印象了,對於get和set我在後面實際應用中再解釋吧~

相關文章
相關標籤/搜索