VUE2—defineProperty和VUE3—proxy使用方式
前言
使用過(guò)vue開(kāi)發(fā)的盆友都知道Vue2和Vue3的響應(yīng)式原理是不一樣的,vue2用的是Object.defineProperty,vue3用的是proxy。那他們具體是什么呢?又有什么區(qū)別呢?
下面叫我簡(jiǎn)單做個(gè)筆記。有什么錯(cuò)誤望各位大佬不吝指點(diǎn)。
什么是Object.defineProperty()
Object.defineProperty是 es5 引入的一個(gè)方法,用于定義或修改對(duì)象的屬性的方法,可以控制屬性的特性(如可枚舉性、可配置性、可寫性等)。
Object.defineProperty()語(yǔ)法
Object.defineProperty(obj, prop, descriptor)
參數(shù)說(shuō)明:
obj
:定義屬性的對(duì)象。prop
:定義或修改的屬性的名稱。descriptor
:屬性的描述符對(duì)象,包含屬性的特性設(shè)置。
descriptor 對(duì)象下包含的屬性:
value
:屬性的值。writable
:屬性是否可寫,即是否可以使用賦值操作符改變屬性值。configurable
:屬性描述符是否可以被改變,或者屬性是否可以被刪除,默認(rèn)為false。enumerable
:屬性是否可枚舉,即是否會(huì)出現(xiàn)在使用 for...in 循環(huán)時(shí)。get
:一個(gè)函數(shù),當(dāng)屬性被讀取時(shí)調(diào)用,返回屬性值。set
:一個(gè)函數(shù),當(dāng)屬性被賦值時(shí)調(diào)用,接收新值作為參數(shù)。
<script> // 定義一個(gè)對(duì)象名為(person)的對(duì)象【對(duì)象的屬性有(name、sex)】 let person = { name: '小明', sex: '男'} //給對(duì)象(person)添加一個(gè)屬性名為(age)的屬性,屬性描述符只包含了 value 屬性,表示 age 屬性的初始值。 Object.defineProperty(person, 'age', { value: 18, // 屬性的值 enumerable: true, // 屬性是否可枚舉 writable: true, // 屬性是否可寫/可修改 configurable: true // 屬性是否可以被刪除 }) console.log(person); </script>
proxy簡(jiǎn)介
Proxy是ES6中的一種用于創(chuàng)建代理對(duì)象的特殊對(duì)象。它允許我們定義自定義行為,例如攔截和修改對(duì)象的默認(rèn)操作。Proxy可以用于攔截對(duì)象的各種操作,包括屬性訪問(wèn)、賦值、函數(shù)調(diào)用等。
Proxy
的構(gòu)造函數(shù)接受兩個(gè)參數(shù):目標(biāo)對(duì)象(被代理的對(duì)象)和一個(gè)處理器對(duì)象(用于定義攔截器)
常用的攔截方法包括:get
、set
、apply
、construct、deleteProperty
、has
、getOwnPropertyDescriptor
等?!?strong>這些攔截方法會(huì)在代理對(duì)象進(jìn)行對(duì)應(yīng)操作時(shí)自動(dòng)觸發(fā)】
注:Proxy詳解見(jiàn)我另一篇文章: ES6之---Proxy簡(jiǎn)介 這里就不過(guò)多敘述了
// 寫法:target是目標(biāo)對(duì)象,handler是處理器對(duì)象 const proxy = new Proxy(target, handler); 簡(jiǎn)單示例 let star = { name: '小明', age: 18 } let proxy = new Proxy(star,{ get(targetObj, propoty, receiver) { console.log(`我是被代理的對(duì)象${targetObj}`) console.log(`我是你訪問(wèn)的被代理的屬性${propoty}`) //receiver是代理對(duì)象proxy return targetObj[propoty] } })
vue中defineProperty和proxy對(duì)比
1.監(jiān)聽(tīng)數(shù)據(jù)的角度
defineproperty
只能監(jiān)聽(tīng)某個(gè)屬性而不能監(jiān)聽(tīng)整個(gè)對(duì)象。proxy
不用設(shè)置具體屬性,直接監(jiān)聽(tīng)整個(gè)對(duì)象。defineproperty
監(jiān)聽(tīng)需要知道是哪個(gè)對(duì)象的哪個(gè)屬性,而proxy
只需要知道哪個(gè)對(duì)象就可以了。也就是會(huì)省去for in
循環(huán)提高了效率。- Object.defineProperty有一個(gè)致命的缺點(diǎn),就是無(wú)法監(jiān)聽(tīng)對(duì)象屬性的新增和刪除;可以使用this.$set和this.$delete解決,這個(gè)方法在項(xiàng)目中也經(jīng)常使用
2.監(jiān)聽(tīng)對(duì)原對(duì)象的影響
- 因?yàn)?code>defineproperty是通過(guò)在原對(duì)象身上新增或修改屬性增加描述符的方式實(shí)現(xiàn)的監(jiān)聽(tīng)效果,一定會(huì)修改原數(shù)據(jù)。
- 而
proxy
只是原對(duì)象的代理,proxy
會(huì)返回一個(gè)代理對(duì)象不會(huì)在原對(duì)象上進(jìn)行改動(dòng),對(duì)原數(shù)據(jù)無(wú)污染。
3.實(shí)現(xiàn)對(duì)數(shù)組的監(jiān)聽(tīng)
- 因?yàn)閿?shù)組
length
的特殊性 (length 的描述符configurable 和 enumerable 為 false,并且妄圖修改 configurable 為 True 的話 js 會(huì)直接報(bào)錯(cuò):VM305:1 Uncaught TypeError: Cannot redefine property: length) defineproperty
無(wú)法監(jiān)聽(tīng)數(shù)組長(zhǎng)度變化,Vue
只能通過(guò)重寫數(shù)組方法的方式變現(xiàn)達(dá)成監(jiān)聽(tīng)的效果,光重寫數(shù)組方法還是不能解決修改數(shù)組下標(biāo)時(shí)監(jiān)聽(tīng)的問(wèn)題,只能再使用自定義的$set
的方式- 而
proxy
因?yàn)樽陨硖匦?,是?chuàng)建新的代理對(duì)象而不是在原數(shù)據(jù)身上監(jiān)聽(tīng)屬性,對(duì)代理對(duì)象進(jìn)行操作時(shí),所有的操作都會(huì)被捕捉,包括數(shù)組的方法和length
操作,再不需要重寫數(shù)組方法和自定義set
函數(shù)了。(代碼示例在下方)
4. 監(jiān)聽(tīng)的范圍
defineproperty
只能監(jiān)聽(tīng)到value
的get set
變化。proxy
可以監(jiān)聽(tīng)除[[getOwnPropertyNames]]
以外所有JS
的對(duì)象操作。(鏈接看下方)監(jiān)聽(tīng)的范圍更大更全面。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于vue-cli配置lib-flexible + rem實(shí)現(xiàn)移動(dòng)端自適應(yīng)
這篇文章主要介紹了基于vue-cli配置lib-flexible + rem實(shí)現(xiàn)移動(dòng)端自適應(yīng),需要的朋友可以參考下2017-12-12VUE3子表格嵌套分頁(yè)查詢互相干擾的問(wèn)題解決方案
這篇文章主要介紹了VUE3子表格嵌套分頁(yè)查詢互相干擾的問(wèn)題解決方案,如果不需要做子表格的分頁(yè)查詢,那么可以直接在主表格中嵌套子表格,本文給大家介紹兩種方式,需要的朋友可以參考下2024-01-01VUE-PDF實(shí)現(xiàn)pdf在線預(yù)覽問(wèn)題
這篇文章主要介紹了VUE-PDF實(shí)現(xiàn)pdf在線預(yù)覽問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-10-10Vue使用Echarts實(shí)現(xiàn)排行榜效果
這篇文章主要為大家詳細(xì)介紹了Vue使用Echarts實(shí)現(xiàn)排行榜效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決
這篇文章主要介紹了vue中使用vant的Toast輕提示報(bào)錯(cuò)的解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05