学习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的值