場景
就算只是扮演,也會成為真實的自我的一部分。對人類的精神來說,真實和虛假其實并沒有明顯的界限。入戲太深不是一件好事,但對于你來說并不成立,因為戲中的你才是真正符合你的身份的你。如今的你是真實的,就算一開始你只是在模仿著這種形象,現在的你也已經成為了這種形象。無論如何,你也不可能再回到過去了。
Proxy 代理,在 JavaScript 似乎很陌生,卻又在生活中無處不在。或許有人在學習 ES6 的時候有所涉獵,但卻并未真正了解它的使用場景,平時在寫業務代碼時也不會用到這個特性。
相比于文縐縐的定義內容,想必我們更希望了解它的使用場景,使其在真正的生產環境發揮強大的作用,而不僅僅是作為一個新的特性 -- 然后,實際中完全沒有用到!
為函數添加特定的功能 代理對象的訪問 作為膠水橋接不同結構的對象 監視對象的變化 還有更多。。。如果你還沒有了解過 Proxy 特性,可以先去MDN Proxy 上查看基本概念及使用。
為函數添加特定的功能
下面是一個為異步函數自動添加超時功能的高階函數,我們來看一下它有什么問題
/** * 為異步函數添加自動超時功能 * @param timeout 超時時間 * @param action 異步函數 * @returns 包裝后的異步函數 */function asyncTimeout(timeout, action) { return function(...args) { return Promise.race([ Reflect.apply(action, this, args), wait(timeout).then(Promise.reject), ]) }}一般而言,上面的代碼足以勝任,但問題就在這里,不一般的情況 -- 函數上面包含自定義屬性呢?
眾所周知,JavaScript 中的函數是一等公民,即函數可以被傳遞,被返回,以及,被添加屬性!
例如下面這個簡單的函數 get,其上有著 _name 這個屬性
const get = async i => iget._name = 'get'
一旦使用上面的 asyncTimeout 函數包裹之后,問題便會出現,返回的函數中 _name 屬性不見了。這是當然的,畢竟實際上返回的是一個匿名函數。那么,如何才能讓返回的函數能夠擁有傳入函數參數上的所有自定義屬性呢?
一種方式是復制參數函數上的所有屬性,但這點實現起來其實并不容易,真的不容易,不信你可以看看 Lodash 的 clone 函數。那么,有沒有一種更簡單的方式呢?答案就是 Proxy,它可以代理對象的指定操作,除此之外,其他的一切都指向原對象。
下面是 Proxy 實現的 asyncTimeout 函數
/** * 為異步函數添加自動超時功能 * @param timeout 超時時間 * @param action 異步函數 * @returns 包裝后的異步函數 */function asyncTimeout(timeout, action) { return new Proxy(action, { apply(_, _this, args) { return Promise.race([ Reflect.apply(_, _this, args), wait(timeout).then(Promise.reject), ]) }, })}
新聞熱點
疑難解答
圖片精選