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();
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
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; // 抛出异常
}
总结&应用场景

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值