• Proxy的has拦截与with关键字


    Proxy的has拦截与with关键字

    Proxy的has钩子可以拦截下面这些操作:

    1. 属性查询:foo in proxy

    2. 继承属性查询:foo in Object.create(proxy)

    3. with 检查: with(proxy) { (foo); }

    4. Reflect.has()

    本文主要就第三条说明

    with关键字

    JavaScript 查找某个未使用命名空间的变量时,会通过作用域链来查找,作用域链是跟执行代码的 context 或者包含这个变量的函数有关。'with’语句将某个对象添加到作用域链的顶部,如果在 statement 中有某个未使用命名空间的变量,跟作用域链中的某个属性同名,则这个变量将指向这个属性值。如果沒有同名的属性,则将拋出ReferenceError异常。

    备注: 不推荐使用with,在 ECMAScript 5 严格模式中该标签已被禁止。推荐的替代方案是声明一个临时变量来承载你所需要的属性。

    举例说明
    class F {
      constructor() {
        this.hobby = "ball";
      }
    }
    class C extends F {
      constructor() {
        super();
        this.name = "Hello"
      }
    }
    
    const obj = new C();
    
    const name = "Nice";
    const age = 20;
    function withTest() {
      console.log(name); // Nice
      console.log(age); // 20
      // console.log(hobby) // Uncaught ReferenceError: hobby is not defined
      with (obj) {
        // 此时 这个块中的context对象是 obj
        // 查找变量时会优先在 obj 上查找,找不到再沿着作用域链往上找
        console.log(name); // Hello
        console.log(age); // 20
        console.log(hobby) // ball
      }
    }
    withTest();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    has拦截举例
    const obj = {
      name: "Eric",
      age: 20
    };
    
    const proxy = new Proxy(obj, {
      // 调用 "name" in proxy 会被has方法拦截
      has(target, key) {
        return true;
      }
    })
    console.log("name" in proxy); // 恒为true
    console.log("name1" in proxy); // 恒为true
    console.log("name2" in proxy); // 恒为true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    has拦截with关键字
    const age = 20;
    class F {
      constructor() {
        this.hobby = "ball";
      }
    }
    class C extends F {
      constructor() {
        super();
        this.name = "Hello"
      }
    }
    
    const obj = new C();
    
    const proxy = new Proxy(obj, {
      has(target, key) {
        // 在这里可以做些处理,比如proxy 如果没有 age 属性,不让继续往上层作用域查找
        // 直接抛出一个异常
        if (!target.hasOwnProperty(key)) {
          throw new Error(`${key} is not defined!!!!!`);
        };
        return true;
      }
    })
    
    with(proxy) {
      name; // 无异常
      age; // 抛出异常
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    总结&应用场景

    讲了几个碎片化的小知识点,应用场景可以是在做沙盒环境隔离这方面。

    比如我想要一个干净的隔离环境,只可以访问定义的环境变量,并且不能通过作用域链访问上层变量,此时可以借助with关键字和Proxy的has拦截器做些事情。

  • 相关阅读:
    go语言实现二叉树的迭代后续遍历
    Android车载蓝牙相关开发4:蓝牙电话操作器BluetoothHeadsetClient
    gcc编译器和gdb调试工具
    前端包管理器:深入理解npm和yarn
    怎样吃透一个java项目?
    拥抱 Spring 全新 OAuth 解决方案
    Python - 通过/SSH 获取远程主机的 env 变量
    展会邀请|虹科诚邀您9月14-16日参加第四届自动驾驶地图与定位大会和第五届自动驾驶与人机共驾论坛
    这可能是目前最全的Redis高可用技术解决方案
    基于改进全卷积一阶检测器的桥梁裂缝定位算法
  • 原文地址:https://blog.csdn.net/mochenangel/article/details/127734870