摘要:概述代理嘛,就是請代理人代替自己做某件事,但是和自己不一樣的是代理人可以有自己的行為,甚至可以做出和預期相違背的行為。
0x000 概述
代理嘛,就是請代理人代替自己做某件事,但是和自己不一樣的是代理人可以有自己的行為,甚至可以做出和預期相違背的行為。
0x001 栗子聲明一個普通對象origin,他有一個屬性name
let origin={ name: "origin" }
聲明一個代理對象
let proxy=new Proxy(origin, { get: (target, key)=>target[key]+" from proxy", set: (target, key, value)=>target[key]="set by proxy "+value })
此時輸出origin和proxy,可以發現,proxy擁有和origin一樣的name屬性
console.log(origin) // {name: "origin"} console.log(proxy) // Proxy {name: "origin"}
為origin添加age屬性,再輸出,可以發現,origin和proxy都擁有了age屬性
origin.age=1 console.log(origin) // {name: "origin", age: "1"} console.log(proxy) // Proxy {name: "origin", age "1"}
那就是代理嗎,當然不是,我們嘗試為proxy添加屬性
proxy.x=1 console.log(origin) // {name: "origin", age: "1", x:"set by proxy 1"} console.log(proxy) // Proxy {name: "origin", age "1"}
可以發現,雖然origin和proxy都擁有了x屬性,但是并不是我們賦值的1,而是多了set by proxy 幾個字符串,很明顯,這里是執行了初始化proxy時傳入的第二個對象的set方法
那如果我們get呢
console.log(proxy.x) // set by proxy 1 console.log(proxy.x) // set by proxy 1 from proxy
現在很清楚了,proxy就是origin的代理,所有在proxy上的操作都會同步到origin上,而對origin的操作卻不會同步到proxy上,而且proxy還有自己的行為。
可以這么想,proxy就是origin的秘書,所有的事務處理都要提交給秘書,秘書有自己的辦事準則,可以直接提交給老板,也可以拒絕提交,或者添加一些其他的行為再提交。那這個秘書到底能代理老板做哪些事呢?
0x002 陷阱
語法
let p = new Proxy(target, handler);
初始化一個代理需要有兩個參數
target:代理目標
handle:陷阱,是一個對象,我們的操作就像一只逃跑的動物,如果獵人在所有可以逃跑的路上全部放滿了陷阱,那我們總是會落入一起一個的。本質就是一個對象,鍵描述我們的操作,值是函數,描述我們的行為,一共有13種陷阱。
0x003 set:設置屬性
語法:
set(target, key, value)
target: 代理對象
`key: 設置的屬性
value: 設置的屬性值
栗子:
let origin={} let proxy=new Proxy(origin,{ set:(target, key, value)=>{ if(value>5)target[key]=value+10000 } }) proxy.x=1 proxy.y=10 console.log(proxy) // Proxy {y: 10010} console.log(origin) // {y: 10010}
說明:
上面我們放置了一個set陷阱,當我們做set操作的時候,就會被捕捉到,我們判斷value是否大于5,如果不大于5我們就不會做任何東西,但是如果大于5,就會給做賦值操作,并且還將他加上了10000。上面的栗子就相當于一個攔截器了。
語法:
get(target, key)
target: 代理對象
`key: 訪問的屬性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ get:(target, key)=>{ if(key==="x")return "no" return target[key] } }) console.log(proxy.x) // "no" console.log(proxy.y) // 20x005 deleteProperty:刪除屬性
語法:
deleteProperty(target, key)
target: 代理對象
`key: 要刪除的屬性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ deleteProperty:(target, key)=>{ if(key==="x")return delete target[key] } }) delete proxy.x delete proxy.y console.log(proxy) // {x:1}0x006 has:判斷是否包含某屬性
語法:
has(target, key)
target: 代理對象
`key: 要判斷的屬性
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ has:(target, key)=>{ if(key==="x")return false return true } }) console.log("x" in proxy) // false console.log("y" in proxy) // true0x007 ownKeys:獲取自身屬性值
語法:
ownKeys(target)
target: 代理對象
栗子:
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ ownKeys:(target)=>{ return ["y"] } }) console.log(Object.getOwnPropertyNames(proxy)) // ["y"]0x008 getPrototypeOf:獲取prototype
語法:
getPrototypeOf(target)
target: 代理對象
栗子
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ getPrototypeOf:(target)=>{ return null } }) console.log(Object.getPrototypeOf(p)) // null0x009 setPrototypeOf:設置prototype
語法:
setPrototypeOf(target, prototype)
target: 代理對象
prototype: 要設置的prototype
栗子
let origin={ x:1, y:2 } let proxy=new Proxy(origin,{ setPrototypeOf:(target, prototype)=>{ throw "no" } }) Object.setPrototypeOf(proxy, {}) // Uncaught no0x010 defineProperty :設置屬性描述
語法:
defineProperty(target, prop, descriptor)
target: 代理對象
prop: 要設置描述的屬性
descriptor: 描述
栗子
let origin={} let proxy=new Proxy(origin,{ defineProperty:(target, prop, descriptor)=>{ throw "no" } }) Object.defineProperty(proxy, "x", {configurable: true}) // Uncaught no0x011 getOwnPropertyDescriptor :獲取自身屬性描述
語法:
getOwnPropertyDescriptor(target, prop)
target: 代理對象
prop: 獲取描述的屬性
栗子
let origin={} let proxy=new Proxy(origin,{ getOwnPropertyDescriptor:(target, prop)=>{ throw "no" } }) Object.getOwnPropertyDescriptor(proxy, "x") // Uncaught no0x012 isExtensible:判斷是否可擴展
語法:
isExtensible(target)
target: 代理對象
栗子
let origin={} let proxy=new Proxy(origin,{ isExtensible:(target)=>{ return false } }) console.log(Object.isExtensible(proxy)); // false0x013 preventExtensions :阻止擴展
語法:
preventExtensions(target)
target: 代理對象
栗子:
let origin={} let proxy=new Proxy(origin,{ preventExtensions:(target)=>{ return false; } }) console.log(Object.preventExtensions(proxy)); // Uncaught TypeError: "preventExtensions" on proxy: trap returned falsish0x014 construct:構造
語法:
construct(target, argumentsList, newTarget)
target: 代理對象
argumentsList: 參數列表
newTarget: 新對象
栗子:
let Origin=function(){} let OriginProxy=new Proxy(Origin,{ construct: function(target, argumentsList, newTarget) { throw "error" } }) new OriginProxy() // Uncaught error0x015 apply:調用
語法:
apply(target, thisArg, argumentsList)
target: 代理對象
thisArg: 上下文
argumentsList: 參數列表
栗子:
let origin=function(){} let proxy=new Proxy(origin,{ apply: function(target, thisArg, argumentsList) { throw "error" } }) origin() // Uncaught error
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108643.html
摘要:方法與代理處理程序的方法相同。使用給目標函數傳入指定的參數。當然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入參數,將返回值賦值給,這樣我們就能在需要讀取這個返回值的時候調用。這種代理模式和的代理有異曲同工之妙。 反射 Reflect 當你見到一個新的API,不明白的時候,就在瀏覽器打印出來看看它的樣子。 showImg(https://segmentfault....
摘要:方法與代理處理程序的方法相同。使用給目標函數傳入指定的參數。當然,不用反射也可以讀取的值。的例子我們可以理解成是攔截了方法,然后傳入參數,將返回值賦值給,這樣我們就能在需要讀取這個返回值的時候調用。這種代理模式和的代理有異曲同工之妙。 反射 Reflect 當你見到一個新的API,不明白的時候,就在瀏覽器打印出來看看它的樣子。 showImg(https://segmentfault....
摘要:同時,迭代器有一個方法來向函數中暫停處拋出一個錯誤,該錯誤依然可以通過函數內部的模塊進行捕獲處理。 本文翻譯自:Diving Deeper With ES6 Generators 由于個人能力有限,翻譯中難免有紕漏和錯誤,望不吝指正issue ES6 Generators:完整系列 The Basics Of ES6 Generators Diving Deeper With E...
摘要:代理和反射的定義調用可常見代替其它目標對象的代理,它虛擬化了目標,所以二者看起來功能一致。代理可攔截引擎內部目標的底層對象操作,這些底層操作被攔截后會觸發響應特定操作的陷阱函數。 代理和反射的定義 調用 new Proxy() 可常見代替其它目標 (target) 對象的代理,它虛擬化了目標,所以二者看起來功能一致。 代理可攔截JS引擎內部目標的底層對象操作,這些底層操作被攔截后會觸發...
閱讀 3643·2021-11-19 09:40
閱讀 3099·2019-08-30 15:54
閱讀 2315·2019-08-30 15:44
閱讀 3197·2019-08-29 15:35
閱讀 3335·2019-08-29 12:22
閱讀 2864·2019-08-28 18:01
閱讀 3146·2019-08-26 13:54
閱讀 905·2019-08-26 12:24