es6基礎 --- 6、Proxy與Reflect vue3.0與2.0 Object.defineProperty的對比

Proxy與Reflect

新建一個代理對象,通過操作代理對象就能操作原對象。Proxy構造函數的兩個參數,一個是需要劫持的對象,一個是操作函數對象。如果不設置操作函數對象,則默認使用Reflect的相關API,也就是說Reflect提供了proxy13種操作函數的默認實現。

                const person = {
			name:'lf',
			age: 19
		}
		const p = new Proxy(person, {
			get(target, property){
				return Reflect.get(target, property)
			},
			set(target, property, value){
				target[property] = value
			}
		})
		console.log(p.name) // 'lf'
		p.age=23
		console.log(p.age) // 23
		console.log(person.age) // 23

常用的proxy劫持操作函數以下幾個:

  • get(target, propKey, receiver):攔截對象屬性的讀取,比如proxy.fooproxy['foo']
  • set(target, propKey, value, receiver):攔截對象屬性的設置,比如proxy.foo = vproxy['foo'] = v,返回一個布爾值。
  • has(target, propKey):攔截propKey in proxy的操作,返回一個布爾值。
  • deleteProperty(target, propKey):攔截delete proxy[propKey]的操作,返回一個布爾值。
  • ownKeys(target):攔截Object.getOwnPropertyNames(proxy)Object.getOwnPropertySymbols(proxy)Object.keys(proxy)for...in循環,返回一個數組。該方法返回目標對象所有自身的屬性的屬性名,而Object.keys()的返回結果僅包括目標對象自身的可遍歷屬性。
  • defineProperty(target, propKey, propDesc):攔截Object.defineProperty(proxy, propKey, propDesc)Object.defineProperties(proxy, propDescs),返回一個布爾值。
  • getPrototypeOf(target):攔截Object.getPrototypeOf(proxy),返回一個對象。
  • apply(target, object, args):攔截 Proxy 實例作爲函數調用的操作,比如proxy(...args)proxy.call(object, ...args)proxy.apply(...)

對應的Reflect方法:

  • Reflect.apply(target, thisArg, args)
  • Reflect.get(target, name, receiver)      in 
  • Reflect.set(target, name, value, receiver)
  • Reflect.defineProperty(target, name, desc)
  • Reflect.deleteProperty(target, name)   delete
  • Reflect.has(target, name)
  • Reflect.ownKeys(target)  Object.keys()
  • Reflect.getPrototypeOf(target)

Reflect的作用:

原來判斷一個對象是否有某屬性 in  現在可以用Reflect.has(target, 'name') 注意對象屬性得是字符串

原來刪除某屬性 delete  現在可以用Reflect.deleteProperty(target, 'name')

原來獲取一個對象的所有屬性 Object.keys()  現在可以用Reflect.ownKeys(target)

綜上,其他的功能請自行使用。Reflect提供了統一的一套操作對象的API

vue3.0與2.0 Object.defineProperty的對比

vue2.0使用Object.defineProperty(target, prop, handler)來劫持對象屬性的相關操作

  1. 只能劫持對象屬性,需要遍歷對象的所有屬性
  2. 無法檢測到對象屬性的添加,vue實例初始化後新添加的對象屬性不具備響應式
  3. Object.defineProperty無法監控到數組下標的變化,導致直接通過數組的下標給數組設置值,不能實時響應,也無法監聽到push等方法,vue中重寫了這些方法來增加setter

3.0 使用es6 proxy來監聽數據的變化

  1. 可以劫持整個對象
  2. 對象新增屬性可以實時響應式,可以檢測到數組下標的變化
  3. 因爲Proxy是ES6新增的屬性,有些瀏覽器還不支持,只能兼容到IE11
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章