前言
不久前,也就是11月14日-16日于多倫多舉辦的 VueConf TO 2018 大會(huì)上,尤雨溪發(fā)表了名為 Vue3.0 Updates 的主題演講,對(duì) Vue3.0 的更新計(jì)劃、方向進(jìn)行了詳細(xì)闡述,表示已經(jīng)放棄使用了 Object.defineProperty,而選擇了使用更快的原生 Proxy !!
這將會(huì)消除了之前 Vue2.x 中基于 Object.defineProperty 的實(shí)現(xiàn)所存在的很多限制:無(wú)法監(jiān)聽(tīng) 屬性的添加和刪除、數(shù)組索引和長(zhǎng)度的變更,并可以支持 Map、Set、WeakMap 和 WeakSet!
做為一個(gè) “前端工程師” ,有必要安利一波 Proxy !!
什么是 Proxy?
MDN 上是這么描述的——Proxy對(duì)象用于定義基本操作的自定義行為(如屬性查找,賦值,枚舉,函數(shù)調(diào)用等)。
官方的描述總是言簡(jiǎn)意賅,以至于不明覺(jué)厲...
其實(shí)就是在對(duì)目標(biāo)對(duì)象的操作之前提供了攔截,可以對(duì)外界的操作進(jìn)行過(guò)濾和改寫(xiě),修改某些操作的默認(rèn)行為,這樣我們可以不直接操作對(duì)象本身,而是通過(guò)操作對(duì)象的代理對(duì)象來(lái)間接來(lái)操作對(duì)象,達(dá)到預(yù)期的目的~
什么?還沒(méi)表述清楚?下面我們看個(gè)例子,就一目了然了~
let obj = { a : 1 } let proxyObj = new Proxy(obj,{ get : function (target,prop) { return prop in target ? target[prop] : 0 }, set : function (target,prop,value) { target[prop] = 888; } }) console.log(proxyObj.a); // 1 console.log(proxyObj.b); // 0 proxyObj.a = 666; console.log(proxyObj.a) // 888上述例子中,我們事先定義了一個(gè)對(duì)象 obj , 通過(guò) Proxy 構(gòu)造器生成了一個(gè) proxyObj 對(duì)象,并對(duì)其的 set(寫(xiě)入) 和 get (讀取) 行為重新做了修改。
當(dāng)我們?cè)L問(wèn)對(duì)象內(nèi)原本存在的屬性時(shí),會(huì)返回原有屬性內(nèi)對(duì)應(yīng)的值,如果試圖訪問(wèn)一個(gè)不存在的屬性時(shí),會(huì)返回0 ,即我們?cè)L問(wèn) proxyObj.a 時(shí),原本對(duì)象中有 a 屬性,因此會(huì)返回 1 ,當(dāng)我們?cè)噲D訪問(wèn)對(duì)象中不存在的 b 屬性時(shí),不會(huì)再返回 undefined ,而是返回了 0 ,當(dāng)我們?cè)噲D去設(shè)置新的屬性值的時(shí)候,總是會(huì)返回 888 ,因此,即便我們對(duì) proxyObj.a 賦值為 666 ,但是并不會(huì)生效,依舊會(huì)返回 888!
語(yǔ)法
ES6 原生提供的 Proxy 語(yǔ)法很簡(jiǎn)單,用法如下:
let proxy = new Proxy(target, handler);
參數(shù) target 是用 Proxy 包裝的目標(biāo)對(duì)象(可以是任何類型的對(duì)象,包括原生數(shù)組,函數(shù),甚至另一個(gè)代理), 參數(shù) handler 也是一個(gè)對(duì)象,其屬性是當(dāng)執(zhí)行一個(gè)操作時(shí)定義代理的行為的函數(shù),也就是自定義的行為。
Proxy 的基本用法就如同上面這樣,不同的是 handler 對(duì)象的不同,handler 可以是空對(duì)象 {} ,則表示對(duì) proxy 操作就是對(duì)目標(biāo)對(duì)象 target 操作,即:
let obj = {} let proxyObj = new Proxy(obj,{}) proxyObj.a = 1; proxyObj.fn = function () { console.log('it is a function') } console.log(proxyObj.a); // 1 console.log(obj.a); // 1 console.log(obj.fn()) // it is a function
新聞熱點(diǎn)
疑難解答
圖片精選