最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • ES6的Proxy ,一颗问路的石子

    正文概述 掘金(蓝色夜晚)   2021-02-17   491

    前言

    let kind = false;
    const person = new Proxy({}, {
        get (target, propKey, receiver) {
            if (propKey === 'kind') {
                return kind = !kind;
            }
            return Reflect.get(target, propKey, receiver)
        }
    });
    if (person.kind && !person.kind) {
        console.log('------');
    }
    // ------
    

    果然成年人的世界不是非黑即白?(远离毒鸡汤)。

    简单介绍

      Proxy 是用于拦截对象访问的ES6特性。外界对代理实例的多数操作可在拦截器中捕获。

    const proxy = new Proxy({}, {
        get(target, propKey, receiver) { },
        set(target, propKey, value, receiver) { },
        has(target, propKey) { },
        deleteProperty(target, propKey) { },
        ownKeys(target) { },
        getOwnPropertyDescriptor(target, propKey) { },
        defineProperty(target, propKey, propDesc) { },
        preventExtensions(target) { },
        getPrototypeOf(target) { },
        isExtensible(target) { },
        setPrototypeOf(target, proto) { },
        apply(target, object, args) { },
        construct(target, args) { }
    });
    

      Proxy 支持拦截以上13种行为,详细的使用方法可以参考ES6入门-Proxy。

      前言中的 Reflect ,可以理解为 Proxy 的『后门』,用于访问原始对象,同样支持13个方法,传参也与 Proxy 一致。

      Proxy 很厉害,看起来可以混淆正常的逻辑判断。

    使用技巧

    问路
    if(input.show) {
    	// input.show == true ?
    } else {
    	// input.show == false ?
    }
    

      上面这段if判断在 input 是拦截器时会失效, show 可以在两次 get 给出不同的结果。如此可以穿透模块的逻辑分支,也就是投石问路的意思。输入端甚至可以通过捕获的内容输出一份日志。

    const proxy = new Proxy({}, {
    	get (target, key) {
          if (key === 'a') {
          	return 1;
          }
        }
    });
    
    console.log(JSON.parse(JSON.stringify(proxy))); // {}
    

    不过,因为深拷贝时获取了代理的『快照』,拦截器在深拷贝后无法生效。不希望公开处理过程时,可以通过深拷贝解决。

    isProxy

    代理可以冒充成功是因为还无法区分拦截器和正常对象。不过拦截器状态需要对内部程序公开,经过拦截器的对象不需要再次包装拦截器。

    const isProxy = Symbol();
    const proxy = new Proxy({}, {
    	get (target, key) {
          if (key === isProxy) {
          	return true;
          }
          return target[key];
        }
    });
    
    console.log(proxy[isProxy]); // true
    

    使用Symbol作为判断拦截器占用的 key 可以避免无意识下与被代理对象冲突。

    Proxy 与 defineProperty

    ProxydefineProperty
    作用于整个对象某个属性生效场景访问属性访问属性修改原始对象IE兼容129Proxy 不会替代 defineProperty,实际使用时按需求选择即可。

    起源地下载网 » ES6的Proxy ,一颗问路的石子

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元