JavaScript進階(十五):proxy 的基本使用 has、get、set、deleteProperty

首先,我們先稍微介紹下 proxy 的歷史。

實際上來說,proxy 它的前身並不是 defineProperty,它的前身其實是另一個東西,叫做 observe。

observe 的作用和 proxy 差不多,也是可以監聽某一個對象的一些修改之類的東西。

但是它已經被廢棄掉了,如果你去查 MDN、W3C 手冊之類的,它都會給你劃一個紅框,告訴你這個東西已經廢棄掉了,建議你用 proxy 代替等等,所以現在極少數還在用或者是知道有 observe 這個東西。

 

那麼接下來,我們的第一個問題莫過於 proxy 怎麼用,其實它的基本使用是非常簡單的。

首先,我們依然和前面一樣,需要先準備一個真實的數據,這個數據是要藏在背後的,它並不會被人真的去修改

然後接下來注意了,和之前就有點不一樣了,我們需要 new 一個 Proxy:

並且,第一個參數你需要告訴它,我要監聽誰:

proxy 翻譯成中文,就是代理的意思。你找他有事嗎?找他有事你跟我說,你別直接找他,就這樣一個意思。

然後第二個參數就是一個 json:

然後在這個 json 裏面有各種各樣的方法。

當然,原來的 defineProperty 其實有點太過於複雜了,所以說在這它有很多東西直接被取消掉了。

那麼在 proxy 這裏面,有幾種方法可以用。

第一種:has。

has,是專門用於 in 操作的,你需要返回一個 true 或者 false。

和我們平常是一樣的用法,比如:

 

第二種 get,第三種 set:

這兩個就不用說了,get 獲取操作,set 設置操作。

 

第四種:delete。

delete 是 js 的關鍵字,所以它不能直接叫 delete,而是叫做 deleteProperty,它是專門用來刪除的。

 

這 4 種是最有用的,接下來,我們不妨來試試。

首先,new Proxy(),它會給我們返回一個對象 p 出來,當然叫什麼名字都行:

接下來,我們就不能再去操作那個原始的數據對象 _data 了。

注意,這跟我們前面說的 defineProperty 有點不一樣。

比如我們來試試:

in _data 就不會觸發 has,而 in p 就會觸發 has 操作,這個是和 defineProperty 不一樣的地方。

注意,defineProperty 你就操作那個原始對象就行。

而 proxy,你需要操作那個新對象。

這是一個小小的區別,當然順便一說,也就因爲這個原因,所以 proxy 性能比 defineProperty 要高。

 

那麼接下來,我們想要來實現這些操作,就得知道它的參數是什麼。

對於 has 來說,有兩個參數:

第一個是 data。這個 data,其實就等價於上面的 _data:

這時候大家可能很奇怪,我們直接用 _data 不就行了嗎?爲什麼還要給我一個?

原因很簡單,它爲了預防一種情況,就是你直接寫進去,壓根就沒給它取名字:

所以 has 的第一個參數是 data,就是你監聽的那個數據對象。

然後第二個參數就是 name,它到底查詢的是哪個屬性:

那麼接下來,我們就做個判斷:

如果這個屬性在我的 data 身上,那麼我就 return true,如果不在就 return false。

 

然後 get 也有兩個參數:

data,你監聽的那個數據對象。(其實它每次都會把這個 data 給你,所以我們上面壓根就不用存)

name,它到底獲取的是哪個屬性。

所以,我們這也來做個判斷:

如果這個 name 在 data 身上,那就直接返回出去。如果不在,就說明沒這個數據,你試圖找我要一個不存在的東西,那我就給你報錯。

 

以及接下來 set,它有 3 個參數,相信不用往下看,就已經猜到都有誰了。

所以你會發現它們幾個都沒有什麼本質的區別。

 

在接下來,還有個 deleteProperty,它也一樣,有兩個參數。

data,從哪刪。

name,刪誰。

 

現在我們就已經認識了 proxy,那接下來,是時候對它做些事情了,如果說和 defineProperty 沒啥區別,那我們爲啥要用它?

首先,我們增加一個 arr,然後在 set 裏面 console 一句話:

你可以看到,我們對 a 進行設置,是有 set 的。

而對 arr 設置,卻沒有打印 set,說明它是沒走 set 的。爲什麼會這樣?

原因非常的簡單,並不是我們用了 proxy 就一切都解決了。

實際上來說,現在跟剛纔是沒變化的,你的這個 proxy 監聽的是誰?

你這個 proxy 監聽的是你讓它監聽的那個東西,也就是 _data:

別說 arr,比如我們換一個 json:

你可以看到,也一樣沒反應。

所以,並不是說 proxy 能夠自動的幫我們解決這一系列的問題,只是說它比 defineProperty 更方便而已。

我們先認清這個事,它在這一點上來說,不處理的情況下,proxy 和 defineProperty 沒什麼區別。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章