Object.defineProperty的侷限性

先說一下MVVM框架的一大特點,數據雙向綁定,它的實現總結一下有以下幾種方式:

  1. 髒檢查 (Angular)
  2. 數據劫持 (Vue)
  3. 發佈-訂閱
  4. 數據模型

而我們今天討論的Object.defineProperty屬於數據劫持的方式,數據劫持中還有和Proxy(代理)方法。這篇博客將簡單對比Vue3.0使用的Proxy,Object.defineProperty有哪些侷限性。

Object.keys(obj),將返回以obj對象所有的可枚舉屬性構成的數組。

Obeject.defineProperty實現雙向綁定的大概思路:

const data = {
	name: ''
};
function say(name) {
	if (name === '李誕') {
		console.log('人間不值得');
	} else if (name === '蔡康永') {
		console.log('真正的貴族');
	} else {
		console.log('來看奇葩說');
	}
}

// 遍歷對象,對其屬性值進行劫持
Object.keys(data).forEach(function(key) {
  Object.defineProperty(data, key, {
    enumerable: true,//可枚舉
    configurable: true,//可改變
    get: function() {
      console.log('get');
    },
    set: function(newVal) {
      // 當屬性值發生變化時我們可以進行額外操作
      console.log(`大家好,我是${newVal}`);
      say(newVal);
    },
  });
});
data.name = '蔡康永'; //真正的貴族

侷限一:
Object.defineProperty無法監聽數組的變化,所以vue在監聽數組的變化時有時不能做到雙向綁定。

而Vue中以下幾種數組的方法可以被監聽到變化:

  1. push()
  2. pop()
  3. shift()
  4. unshift()
  5. splice()
  6. sort()
  7. reverse()

除此之外,數組的變化時監聽不到的,例如,vm.items[indexOfItem] = newValue;不會被監聽到的。

侷限二:
Object.defineProperty監聽的是對象的屬性,當監聽的對象有很多層級構成,則需要遞歸對象直至基本類型,才能進行監聽,比較麻煩。相比Proxy監聽整個對象的方式,就方便很多。

對比Object.defineProperty和Proxy兩種實現數據劫持方式的區別:

Object.defineProperty proxy
監聽對象的屬性的變化 監聽整個對象
無法監聽屬性是數組的情況 可以監聽屬性是數組的情況
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章