摘要:方法與代理處理程序的方法相同。使用給目標函數傳入指定的參數。當然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入參數,將返回值賦值給,這樣我們就能在需要讀取這個返回值的時候調用。這種代理模式和的代理有異曲同工之妙。
反射 Reflect
當你見到一個新的API,不明白的時候,就在瀏覽器打印出來看看它的樣子。
反射的概念Reflect 是一個內置的對象,它提供可攔截JavaScript操作的方法。方法與代理處理程序的方法相同。Reflect 不是一個函數對象,因此它是不可構造的。
new Reflect() //錯誤的寫法反射的使用
Reflect提供了一些靜態方法,靜態方法是指只能通過對象自身訪問的的方法,這個知識在前面幾章講解過。所有方法的詳細解析,前往 Reflect詳解 查看。
靜態方法列表:這么多靜態方法,你需要學會的是如何使用它們。
1、Reflect.apply()
2、Reflect.construct()
3、Reflect.defineProperty()
4、Reflect.deleteProperty()
5、Reflect.enumerate()
6、Reflect.get()
7、Reflect.getOwnPropertyDescriptor()
8、Reflect.getPrototypeOf()
9、Reflect.has()
10、Reflect.isExtensible()
11、Reflect.ownKeys()
12、Reflect.preventExtensions()
13、Reflect.set()
14、Reflect.setPrototypeOf()
靜態方法的使用:
demo1:使用Reflect.get()獲取目標對象指定key的value。
let obj = { a: 1 }; let s1 = Reflect.get(obj, "a") console.log(s1) // 1
demo2:使用Reflect.apply給目標函數floor傳入指定的參數。
const s2 = Reflect.apply(Math.floor, undefined, [1.75]); console.log(s2) // 1進一步理解Reflect
看了上面的例子和方法,我們知道Reflect可以攔截JavaScript代碼,包括攔截對象,攔截函數等,然后對攔截到的對象或者函數進行讀寫等操作。
比如demo1的get()方法,攔截obj對象,然后讀取key為a的值。當然,不用反射也可以讀取a的值。
再看demo2的apply()方法,這個方法你應該比較了解了,和數組中使用apply不同的是,Reflect.apply()提供了3個參數,第一個參數是反射的函數,后面2個參數才是和數組的apply一致。demo2的例子我們可以理解成是攔截了Math.floor方法,然后傳入參數,將返回值賦值給s2,這樣我們就能在需要讀取這個返回值的時候調用s2。
//數組使用apply const arr = [1, 2, 3] function a() { return Array.concat.apply(null, arguments) } const s = a(arr) console.log(s) // [1, 2 ,3]
其實Reflect的作用和我們下面要講的Proxy是差不多的。
代理 ProxyProxy這個詞相信你已經聽過無數遍了,我曾經寫過一篇webpack使用代理來攔截指定域的API請求,轉發到新的目標URL的文章 webpack中使用proxy。但是注意Proxy和proxy,大小寫字母之間是不同的。本章講的是大寫字母開頭的Proxy。
語法let p = new Proxy(target, handler);
target:一個目標對象(可以是任何類型的對象,包括本機數組,函數,甚至另一個代理)用Proxy來包裝。
handler:一個對象,其屬性是當執行一個操作時定義代理的行為的函數。
基礎demo:Proxy的demo有很多,我們只分析基礎demo,主要看new Proxy({}, handler)的操作,指定目標obj對象,然后handler對象執行get()操作,get()返回值的判斷是,如果name是target目標對象的屬性,則返回target[name]的值,否則返回37,最后測試的時候,p.a是對象p的key,所以返回a的value,而p.b不存在,返回37。
const obj = { a: 10 } let handler = { get: function(target, name){ console.log("test: ", target, name) // test: {"a":10} a // test: {"a":10} b return name in target ? target[name] : 37 } } let p = new Proxy(obj, handler) console.log(p.a, p.b) // 10 37
這個例子的作用是攔截目標對象obj,當執行obj的讀寫操作時,進入handler函數進行判斷,如果讀取的key不存在,則返回默認值。
我們使用一些http-proxy插件或者webpack的時候,有時候需要訪問某個api時,跳轉到指定的url,這種方式也能解決跨域訪問。這種代理模式和Proxy的代理有異曲同工之妙。但是,別混為一體了。
module.exports = { devServer: { proxy: [ { context: "/api/*", //代理API target: "https://www.hyy.com", //目標URL secure: false } ] } }總結
無論是反射還是代理,除了他們使用方法不同之外,他們所作的事情非常相似,都可以理解成攔截某個東西,然后執行某個函數操作,再返回函數操作的結果。
大部分前端在日常業務需求中,幾乎很少使用到這2個API,實際使用場景還得在以后的開發中慢慢挖掘。
=> 返回文章目錄
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/88341.html
摘要:方法與代理處理程序的方法相同。使用給目標函數傳入指定的參數。當然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入參數,將返回值賦值給,這樣我們就能在需要讀取這個返回值的時候調用。這種代理模式和的代理有異曲同工之妙。 反射 Reflect 當你見到一個新的API,不明白的時候,就在瀏覽器打印出來看看它的樣子。 showImg(https://segmentfault....
摘要:是陷阱函數對應的反射方法,同時也是操作的默認行為。對象外形指的是對象已有的屬性與方法的集合,由于該屬性驗證只須在讀取屬性時被觸發,因此只要使用陷阱函數。無論該屬性是對象自身的屬性還是其原型的屬性。 主要知識點:代理和反射的定義、常用的陷阱函數、可被撤銷的代理、將代理對象作為原型使用、將代理作為類的原型showImg(https://segmentfault.com/img/bVbfWr...
摘要:代理和反射的定義調用可常見代替其它目標對象的代理,它虛擬化了目標,所以二者看起來功能一致。代理可攔截引擎內部目標的底層對象操作,這些底層操作被攔截后會觸發響應特定操作的陷阱函數。 代理和反射的定義 調用 new Proxy() 可常見代替其它目標 (target) 對象的代理,它虛擬化了目標,所以二者看起來功能一致。 代理可攔截JS引擎內部目標的底層對象操作,這些底層操作被攔截后會觸發...
摘要:最近買了深入理解的書籍來看,為什么學習這么久還要買這本書呢主要是看到核心團隊成員及的創造者為本書做了序,作為一個粉絲,還是挺看好這本書能給我帶來一個新的升華,而且本書的作者也非常厲害。 使用ES6開發已經有1年多了,以前看的是阮一峰老師的ES6教程,也看過MDN文檔的ES6語法介紹。 最近買了《深入理解ES6》的書籍來看,為什么學習ES6這么久還要買這本書呢?主要是看到Daniel A...
閱讀 1433·2021-09-03 10:29
閱讀 3457·2019-08-29 16:24
閱讀 2010·2019-08-29 11:03
閱讀 1409·2019-08-26 13:52
閱讀 2924·2019-08-26 11:36
閱讀 2785·2019-08-23 17:19
閱讀 559·2019-08-23 17:14
閱讀 811·2019-08-23 13:59