前言
Proxy是ES6引入的一个新的概念。
它的用途是从语言层面上去操作一个对象
这么说太抽象了,当我没说,看代码吧
Proxy之从一个小🌰说起
假如我们有一个人,叫做Bob Wood。
我们这样形容他:
1 | var user = {}; |
想要获取full_name,我们是手动相加了,如果有很多个这样的人,我们懒得写那么多代码,我们就可以写个方法。
1 | var user = { |
此处我们调用方法来给我们实现属性的合并。
以上是ES5里面的办法。在ES6里面,我们有一个更先进的解决办法:
1 | var user = new Proxy({},{ |
现在输出user.full_name,你会发现你没有调用方法,却仍然成功输出了合并后的结果。😄!
Proxy之对小🌰的完善和解释
楼上的代码,我们确实实现了我们想要做到的效果。
不过这时候,如果你输出user.fname,user,lname,甚至输出个根本不存在的user.age,管你输出啥,你会发现他输出的全都是”Bob Wood”。
是不是有毒?????
这就要从Proxy的实质说起了。
首先Proxy它是一个全新的全局构造函数。
上面已经表现得很明显了,毕竟它也是new出来的嘛。
这个构造函数创建对象的形式是这样的:
1 | var proxy = new Proxy(target, handler); |
target,目标对象,handler,句柄。
目标对象的形式就是各种对象,句柄对象(也叫处理器对象)这个名字看上去很厉害,控制所生成代理对象的各种行为,它的实质也是一个对象,不过这个对象必须长这样:
1 | { |
它只能由对象的内部方法组成,句柄方法的完整列表可以在MDN有关代理的页面上找到,一共有14种方法,与ES6中定义的14中内部方法一致。
不过见到比较多的还是覆盖set和get。
句柄的作用,就是你原有对象里面的方法,如果句柄对象里也有,那么句柄对象里面的新方法会覆盖你原有的旧方法
可以把它想象成一个拦截,所有的属性的获取都需要经过这个句柄对象里面的get,其它方法亦然。
因此上面那个例子,所有对象属性的获取都被我们覆写的这一个get给拦截了,因此如果我们想要得到正确的结果,应该这样做:
1 | var user = new Proxy({},{ |
如此,就可以输出我们想要的结果了。
结语
ES5里面的get 属性名()和set 属性名(value),这种新的方法形式让我印象很深刻。
ES6更进一步,推出了能够操作所有内部方法的Proxy构造函数,拓展了原有的构造函数,使我们对对象的操作更加灵活了。