JavaScript進階(十七):如何用 proxy 做一個響應類

這裏我們主要來說下 proxy 的 construct。

在上篇博客中,我們有說到 proxy 的 construct,它裏面會要求你返回一個構造好的對象出來。

那麼現在我想做一個事:

比如上篇博客的例子,這個 p,現在我希望它能夠幫我們去監聽 class A 裏面所有的屬性。

但凡只要是有屬性上的改動,我們希望能夠得到一個通知。

那麼我們應該怎麼做?

 

其實我們有兩種套路,第一種套路可以直接這麼來:

我先創建一個普通類。

只不過,我需要用這個 proxy,來包一層:

那這麼做行不行?其實是可以的。

比方說現在我們就做一個最簡單的例子:

假設 class A 裏面有個 render,因爲我們對類的監聽,基本上到最後 99% 是要去更新這個視圖,或者更新一些別的東西,所以用這個 render 就很有代表性。

然後我們希望的就是,這個 a,它有任何數據上的操作,比如 a.name='大木'

那麼我希望在這個時候就可以觸發它的渲染:

如果我想完成這樣一個工作,應該怎麼辦?

其實還是很簡單的,我們需要去響應它的 set,因爲賦值就是 set 操作嘛。

然後我們需要做兩件事:

第一,我得把這個數據加上去。

第二,我需要去調用它的 render。

現在這時候你可以看到,這個渲染就出來了。

並且,我們再加個 age:

你可以看到,也渲染了。

 

換句話說,用這種簡單的方法,我確實可以做到,不論數據發生什麼變化的時候,我都去觸發這個渲染的操作,這個絕對行。

但是有一個問題,就是這麼寫太麻煩了,你說我每次都要寫這麼多,就有點費勁:

 

所以接下來,我們還有另一個套路,我可以這麼寫:

我在這邊 proxy 的,並不是真正 new 出來的那個結果、那個實例。

而是,我把它整個類,全都丟在這裏面:

大家看到這個可能有一點眼熟,有沒有覺得跟我們前面的某一篇博客,說過的東西有點相似?

其實跟我們之前說的高階類差不多,也是在它之上去附加一層東西。

然後我現在相當於這個類,我並沒有真的去用

我真正用的,是它出來以後的這個玩意。

那麼在這裏面,我要怎麼去做呢?

首先,我需要去響應一個東西,這時候我們就不能用 set 了,我需要去響應它的 construct 操作:

爲什麼要響應 construct 呢?

因爲現在我監聽的,我給它 proxy 起來的,是一個類。

 

那麼在這個 construct 裏面,我需要做什麼呢?

很簡單,將來用的時候,不是有人會 new 這個 A 嗎,那 new 了這個 A 之後,我要幹什麼?

我其實需要去 new 這個 cls,爲什麼?

因爲它纔是那個真正有功能的類。

並且,new 完之後的這個結果,注意,我不能直接返回出去。

如果就這麼直接返回出去了,說白了,沒什麼效果。

不信的話,我們可以試試。

在試之前,我們先做個對比。

這裏注意,上面的這些代碼都不重要,關鍵是用起來方不方便。

第一個套路里面,用這個類的人,他比較麻煩,他需要去 new proxy 等等一系列的事。

而在我們這,相當於我們把那個複雜的操作,放到我們的內部了,他用起來比較方便,這是區別。

 

然後我們繼續。

直接就把 obj 給返回出來了,它就是一個普通的對象,普通對象是沒有響應操作的:

可以看到,不響應,也沒任何的反應。

那怎麼辦?

所以我要 return 的是一個 proxy:

然後在它裏面,我要它的 set 操作:(別的操作也可以做,但現在 set 對我們來說是最重要的)

然後我要的是,真正的去完成這個操作,並且調用 render:

那麼這個時候,我們再試一次:

這個時候,你可以看到:

對於我使用來說,基本沒增加什麼負擔,而控制檯出來的對象本身,它就是一個可以響應的狀態,這個就是我們所要的。

 

所以說白了,這兩種套路區別其實差不多。

最終的一個結果都是差不多的,都是給 new 出來的這個類,去添加一層可響應的東西。

只不過,一個是在外面來做的:

這樣的問題就在於,需要用這個類的人去動手,這個就很麻煩。

而另一種,我把它完全的封閉在裏面了:

這樣的話,用這個類的人就會很輕鬆。

這兩種套路沒別的,就爲這個。

 

所以到這裏,我們基本就看到了,這個 proxy,它比我們的 defineProperty 要強大很多,多了很多的功能,比如 apply,construct。

當然也多了很多的複雜,可以看到它用起來,比 defineProperty 要複雜一些,因爲它裏面有很多其他的操作,會有點亂。

所以下篇博客,我們就在真正的使用當中,對它更進一步的來有一些認識。

 

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