zoukankan      html  css  js  c++  java
  • ES6-Proxy and Reflect

    依赖文件地址 :https://github.com/chanceLe/ES6-Basic-Syntax/tree/master/js

      1 <!DOCTYPE html>
      2 <html>
      3     <head>
      4         <meta charset="UTF-8">
      5         <title>[es6]-10-Proxy和Reflect</title>
      6         
      7         <script src="./js/browser.js"></script>
      8         <script type="text/babel">
      9             /*
     10              * proxy用于修改某些操作的默认行为,等同于在语言层面作出修改,属于一种元编程。
     11              * 叫做代理器。提供了一种机制,可以对外界的访问进行过滤和改写。
     12              */
     13             var obj = new Proxy({},{
     14                 get:function(target,key,receiver){
     15                     console.log(`getting ${key}`);
     16                     return Reflect.get(target,key,receiver);
     17                 },
     18                 set:function(target,key,receiver){
     19                     console.log(`setting ${key}`);
     20                     return Reflect.set(target,key,receiver);
     21                 }
     22             })
     23             //上面代码对一个空对象架设了一层拦截,重定义了属性的读取和设置行为。
     24             obj.count = 1;
     25             ++obj.count;
     26             //结果 表明,Proxy实际上重载了点运算符。
     27             
     28             /*
     29              * es6原生提供Proxy构造函数,用来生成Proxy实例。
     30              * var proxy = new Proxy(target,handler);
     31              * Proxy对象的所有用法,都是上面这种形式,不同的只是Handler参数的写法。target 是目标对象,
     32              * handler参数也是一个对象,用来定制拦截行为。
     33              */
     34             
     35             var proxy1 = new Proxy({},{
     36                 get:function(target,property){
     37                     return 35;
     38                 }
     39             })
     40             console.log(proxy1.time);  //35
     41             console.log(proxy1.name);   //35
     42             
     43             /*
     44              * 要使Proxy起作用,必须对proxy实例进行操作,如果handler没有设置任何拦截,那就等同于直接通向原对象。
     45              * 一个技巧是将Proxy对象,设置到object.proxy属性,从而可以在object对象上调用。
     46              * var object = {proxy:new Proxy(target,handler)};
     47              * 
     48              * Proxy实例也可以作为其他对象的原型对象。
     49              * 
     50              * 下面是Proxy支持的拦截操作表:
     51              * 1.get(target,propKey,receiver)
     52              *     拦截对象属性的读取,比如点或方括号运算符。最后一个参数是一个对象,可选,参见Reflect.get部分。
     53              * 2.set(target,propKey,value,receiver)
     54              *     拦截对象属性的设置,返回一个布尔值。
     55              * 3.has(target,propKey)
     56              *     拦截propKey in proxy的操作,以及对象的hasOwnproperty方法,返回一个布尔值。
     57              * 4.deleteProperty(target,propKey)
     58              *      拦截delete proxy[propKey]的操作,返回一个布尔值。
     59              * 5.ownKeys(target)
     60              *         拦截Object.getOwnPropertyNames(proxy),Object.getOwnpropertySymbols(proxy)
     61              *         Object.keys(proxy),返回一个数组。该方法返回对象所有自身的属性,而Object.keys仅返回对象可遍历属性。
     62              * 6.getOwnPropertyDescriptor(target,propKey)
     63              *         拦截Object.getOwnPropertyDescvriptor(target,propKey),返回属性的描述对象。
     64              * 7.defineProperty(target,propKey,propDesc)
     65              *      拦截Object.defineProperty(target,propKey,propDesc)和Object.defineProperty(target,
     66              *         propDescs)返回一个布尔值。
     67              * 8.preventExtensions(target)
     68              *         拦截Object.preventExtensions(proxy),返回一个布尔值。
     69              * 9.getPrototypeOf(target)
     70              *         拦截Object.getPrototypeOf(proxy),返回一个对象。
     71              * 10.isExtensible(target)
     72              *         拦截Object.isExtensible(target),返回一个布尔值。
     73              * 11.setPrototypeOf(target,proto)
     74              *         拦截Object.setPrototypeOf(target,proto),返回一个布尔值。
     75              * 12.apply(target,object,args)
     76              *         拦截Proxy实例作为函数调用的操作,比如proxy(...args),proxy.call(object,...args)
     77              *         proxy.apply(...)
     78              * 13.construct(target,args)
     79              *         拦截Proxy实例作为构造函数调用的操作,比如 new proxy(...args)。
     80              * 
     81              * 
     82              * 暂时不细琢磨。先跳过
     83              */
     84             
     85             /*
     86              * Proxy.revocable()  该方法返回一个可取消的 Proxy实例。
     87              */
     88             let target = {};
     89             let handler = {};
     90             
     91             let {proxy,revoke} = Proxy.revocable(target,handler);
     92             console.log(proxy)
     93             proxy.foo = 123;
     94             console.log(proxy.foo);  //123
     95             revoke();
     96             console.log(proxy.foo);  //报错 revoked
     97             
     98             
     99             /*
    100              * Reflect
    101              * Reflect对象与Proxy对象一样,也是es6为了操作对象而提供的新API。
    102              * 设计目的如下:
    103              * 1.将Object对象上一些明显属于语言内部的方法(比如Object.defineProperty),放到Reflect对象上,现阶段,
    104              *        某些方法同时在Object和Reflect对象上部署,未来的新方法将只部署在Reflect上。
    105              * 2.修改某些Object方法的返回结果,让其变得更加合理。比如,Object.defineProperty(obj,name,desc)在无法
    106              *      定义属性时,会抛出错误,而Reflect.defineProperty(obj,name,desc)则会返回false。
    107              * 
    108              * 3.让Object操作都变成函数行为。某些Object操作是命令式的,比如name in obj 和delete obj[name],
    109              *   Reflect.has(obj,name)和Reflect.deleteProperty(obj,name)让它们变成了函数行为。
    110              * 
    111              * 4.Reflect对象的方法与Proxy对象的方法一一对应,只要是Proxy对象的方法,就能在Reflect对象上找到对应的方法。
    112              *        这就让proxy对象可以方便地调用对应的Reflect方法,完成默认行为,作为修改行为的基础。也就是说,不管Proxy怎么修改默认
    113              *        行为,你总可以在Reflect对象上获取默认行为。
    114              * 
    115              * Reflect对象的方法共13个,大部分与Object对象的同名方法的作用是相同的,而且它与Proxy对象的方法是一一对应的。
    116              * 
    117              * Refect.get(target,name,receiver)
    118              *   查找并返回target对象的name属性,如果没有该属性,返回undefined。
    119              *   如果name属性部署了读取函数,则读取函数的this绑定receiver。
    120              */
    121         </script>
    122     </head>
    123     <body>
    124     </body>
    125 </html>
  • 相关阅读:
    js 中for forEach map some every的区别
    2019.3.27面试
    js中的继承
    关于iPhone手机上的浏览器、微信内置浏览器不识别yyyy-mm-dd格式的时间显示为NaN问题
    一个有关ajax去获取天气预报然后用echarts展现出来的小demo
    js中var和let的快速区别
    配置服务器-------------适合小白和从未接触过服务器的人阅读
    .net core 响应的json数据驼峰显示问题。
    asp .net core中swagger的简单使用
    关于修改.net core webapi中null默认返回的状态码。
  • 原文地址:https://www.cnblogs.com/chengyunshen/p/7191661.html
Copyright © 2011-2022 走看看