Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

ES6 Proxy的基本概念与实现原理

  访问一个对象的属性时候会调用其内置方法,如果我们劫持了对象本身用于操作属性读写的内置方法就可以自己处理对象的任意属性被访问时的行为了。但是一般对象的这些内置方法当然不是随便给劫持的,只有在Proxy对象中他们才是可以设置其访问处理方法。
  在介绍Proxy之前先介绍一下ES5和ES6中一些内置方法的差异。在ES5中读写对象属性的内置方法名为[[Get]]和[[Put]],而在ES6中则换成了[[Get]]和[[Set]]。不仅是换了个名字,实现过程也已经完全不同了。在ES5中,[[Get]]内置方法需要调用[[GetProperty]]来处理原型链。而ES6中删除了[[GetProperty]]这个方法,而是直接递归[[Get]]方法来处理原型链。ES5中的[[Put]]方法写入数据时还需要调用个[[CanPut]]来检测属性的可写性,当然[[CanPut]]中也用到了[[GetProperty]]来检测原形链中操作属性的[[Writable]]等参数。但在ES6中,这个检测和写入的工作全被放入了[[Set]]内置方法中处理。
  当我们访问一个属性时,先不管这个属性存不存在,直接把访问的属性名交给[[Get]]或[[Set]]处理的。属性存不存在也是在这两个内置方法中检测的。Proxy对象重写了[[Get]]和[[Set]]内置方法,在检测属性是否存在之前就执行我们提供的动作。这样我们就可以对任意属性名做动作,或者说把属性访问定义成自己的函数。
<script>
//Firefox Only
var base,proxy;
base={name:"次碳酸钴"};
var proxy=new Proxy(base,{
  get:function(base,name){
    return base[name];
  },set:function(base,name,value){
    base[name]=value;
  }
});
console.log(proxy.name); //次碳酸钴 //调用get从base上取值
proxy.test="test"; //调用set,并把相应属性名设置到base上
console.log(base.test); //test //调用get从base上取值
console.log(proxy.hasOwnProperty("test")); //true
delete base.test;
console.log(proxy.hasOwnProperty("test")); //false
</script>
  直接调用proxy上的hasOwnProperty判断属性存在时返回true?但我们把基对象上的相应属性删除掉之后在proxy上也能同步。实际上不仅是[[Get]]和[[Set]],很多方法都在proxy上被重写了,所以使用起仿佛在操作基对象一样。具体有哪些可用的操作可以看MDN。但目前ES6也只是草案,也许将来会修改这些东西,不过我觉得可能性已经不大了。
网名:
54.144.24.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^