學習es6的新語法糖既能學習到新東西,又能使得本身的代碼更加優雅,逼格更高,爽
proxy與Reflect之間的運用就是Reflect對對象的操做觸發Proxy的攔截es6
get與set
;語法形式var proxy = new Proxy(target, handler)
; target
是須要操做的對象,而handler
是包含操做target
對象的一些方法的對象Object
的相關方法proxy
: get(target, propKey, receiver)
=>依次爲目標對象、屬性名和 proxy 實例自己(嚴格地說,是操做行爲所針對的對象),其中最後一個參數可選。數組
let obj = { a: 'foo', b: 'Proxy', foo: '' } let proxy = new Proxy(obj, { get (target, proKey, receive) { console.log(target === obj) //true return '當對proxy進行取值操做時會觸發這個get函數' } })
ps:proxy
對target
進行了代理,target就是obj對象,receive用於規定this到底指向哪一個對象,app
proxy.foo //當對proxy進行取值操做時會觸發這個get函數
上面這種狀況並無改變this的,因此console.log(receive === proxy) //true
Reflect也有get方法:Reflect.get(target, prokey, receive)
函數
Reflect.get(proxy, 'foo') //同上沒有this的指向
let newobj = { foo: 'this指向將改變' } Reflect.get(proxy, 'foo', newobj) //foo = console.log(receive === proxy) //true
因此對Reflect.get的第三個參數進行賦值將帶入帶proxy的get的第三個參數中學習
與get相似,這個是賦值時會觸發set方法
proxy: set(target, propKey, value, receiver)
this
let obj = {} let newobj = { a: '123' } let proxy = new Proxy(obj, { set (target, proKey, value, receive) { return target[proKey] = `當對proxy進行賦值操做時會觸發這個set函數${value}` } }) proxy.a = 666 //receive === proxy true Reflect.set(proxy, 'a', 888) //receive === proxy true Reflect.set(proxy, 'a', 888, newobj) //receive === newobj true
proxy的apply:apply(target, object, args)
代理
let twice = { apply (target, ctx, args) { console.log(ctx) //undefined return Reflect.apply(...arguments); } } function sum (left, right) { this.num = 888 /若是ctx沒有傳入或者傳入null,則會進行window.num = 888的賦值 return left + right + this.nm } let obj = { nm: 666 } var proxy = new Proxy(sum, twice); console.log(proxy(1, 2)) // 6 console.log(proxy.apply(obj, [7, 8])) //ctx則爲obj,並改變return
執行流程:proxy觸發函數調用,執行apply的方法,將參數自動帶入,target
就是sum
函數,ctx
沒有傳入爲undefined
,args
爲1, 2
,接下來將所有參數帶入執行Reflect.apply
code
has比較簡單,是對對象進行in運算,判斷該屬性是否存在對象中,能夠是自身也能夠是原型鏈上,無論是否可遍歷對象
在構造函數new時觸發,原型鏈
var p = new Proxy(function () {}, { construct: function(target, args, newTarget) { console.log('called: ' + args.join(', ')); console.log(newTarget === p) return { value: args[0] * 10 }; } }); console.log((new p(1)).value) //等價於下面,Reflect.construct(target, args), args必須是數組 console.log(Reflect.construct(p, [1]))
返回對象中自身的全部屬性,固然具體仍是取決於return 什麼內容;
觸發條件: Object.getOwnPropertyNames() Object.getOwnPropertySymbols() Object.keys() for...in循環
let target = { a: 1, b: 2, c: 3, [Symbol.for('secret')]: '4', }; Object.defineProperty(target, 'key', { enumerable: false, configurable: true, writable: true, value: 'static' }); let handler = { ownKeys(target) { return ['a', 'd', Symbol.for('secret'), 'key']; } }; let proxy = new Proxy(target, handler); console.log(Object.keys(proxy)) //自動過濾symbol,不存在的屬性,不可遍歷的屬性 console.log(Reflect.ownKeys(proxy)) //返回handler中return的值