關於 Object.defineProperty()

這個東東其實沒那麼難,先來看看它的功能和使用方式:框架

Object.defineProperty(obj, prop, descriptor)mvvm

  • obj: 須要定義屬性的對象。
  • prop: 需定義或修改的屬性的名字。
  • descriptor: 將被定義或修改的屬性的描述符。函數

  • 返回值:返回傳入函數的對象,即第一個參數obj。this

三個參數都是必填的spa

關於描述符 descriptor

對象裏目前存在的屬性描述符有兩種主要形式:數據描述符和存取描述符。數據描述符是一個擁有可寫或不可寫值的屬性。存取描述符是由一對 getter-setter 函數功能來描述的屬性。描述符必須是兩種形式之一;不能同時是二者。code

數據描述符和存取描述符均具備如下可選鍵值:

  • configurable
    當且僅當該屬性的 configurable 爲 true 時,該屬性描述符纔可以被改變,也可以被刪除。默認爲 false。對象

  • enumerable
    當且僅當該屬性的 enumerable 爲 true 時,該屬性纔可以出如今對象的枚舉屬性中。默認爲 false。遞歸

數據描述符同時具備如下可選鍵值:

  • value
    該屬性對應的值。能夠是任何有效的 JavaScript 值(數值,對象,函數等)。默認爲 undefined。ip

  • writable
    當且僅當該屬性的 writable 爲 true 時,該屬性才能被賦值運算符改變。默認爲 false。get

存取描述符同時具備如下可選鍵值:

  • get
    一個給屬性提供 getter 的方法,若是沒有 getter 則爲 undefined。該方法返回值被用做屬性值。默認爲 undefined。

  • set
    一個給屬性提供 setter 的方法,若是沒有 setter 則爲 undefined。該方法將接受惟一參數,並將該參數的新值分配給該屬性。默認爲 undefined。

具體示例:

var o = {};
// o.mm = 'lyt'
Object.defineProperty(o, 'mm', {
    value: 'lyt',
    configurable: true,
    enumerable: true,
    writable: true
});
// 這種寫法和上面的是一個意思。

若是configurable爲默認值false,那麼再去修改除writeable之外的屬性都會拋出異常,也就是說這個屬性是個總開關。

var o = {};

Object.defineProperty(o, 'mm', {
    value: 'lyt'
});

Object.defineProperty(o, 'mm', {  // 報錯
    configurable: true
});

若是enumerable爲默認值false,則該屬性不能被for-in循環所遍歷。

var o = {};

Object.defineProperty(o, 'mm', {
    value: 'Tina',
    enumerable: true
});

Object.defineProperty(o, 'name', {
    value: 'lyt'
});

for(var key in o){
    console.log(o[key]); // Tina
}

若是writable爲默認值false,那麼屬性將不可寫,只能讀。

var o = {};

Object.defineProperty(o, 'mm', {
    value: 'Tina'
});

o.mm = 'lmm';

console.log(o.mm)  // Tina

關於 get 和 set 函數

經過Object.defineProperty()來設置存儲描述符的時候,當對對應的數據進行讀取操做的時候會觸發get函數,對數據進行寫入操做的時候會觸發set函數,下面這個例子就會讓你搞清楚它們的做用:

var o = {};

Object.defineProperty(o, 'mm', {
    get:function (){
        console.log('盧雨婷大美妞取了個人值');
        return 'Tina'  // 返回值即便讀取的值
    },
    set:function (value){  // 這個參數的名字隨便
        console.log(`個人值被盧小妞設置成了${value}`);
        // 這裏使用this.mm = value賦值要注意,會造成遞歸。
    }
});

o.mm;
o.mm = '白癡';

至於取值和賦值的時候的行爲,就隨需求而定了。

應用:MVVM框架的基本原理

<div>
    <p>你好: <span id="name">111</span></p>
    <div id="intname">222</div>
</div>
<script>
    var userInfo = {};  // 模擬後臺數據
    
    // 當對數據取值和賦值的時候對DOM進行相應的更新
    Object.defineProperty(userInfo,'name', { 
      get:function () {
        return document.getElementById('name').innerHTML;
      },
      set:function (value) {
        document.getElementById('name').innerHTML = value;
      }
    })
    
    Object.defineProperty(userInfo,'intname', {
      get:function () {
        return document.getElementById('intname').innerHTML;
      },
      set:function (value) {
        document.getElementById('intname').innerHTML = value;
      }
    })
    
    console.log(userInfo.name);
    
    userInfo.name = 'lyt';
    userInfo.intname = 'Tina';
    
    console.log(userInfo.name);
</script>

總結:以上,你沒看錯,就這麼簡單。

相關文章
相關標籤/搜索