代码之家  ›  专栏  ›  技术社区  ›  FZs kangax

对代理使用'with'语句是一种不好的做法吗?

  •  3
  • FZs kangax  · 技术社区  · 5 年前

    首先, with 已弃用 通常地 坏习惯

    Proxy 对象作为


    背景

    eval ,创建值为的常量变量 undefined 具有 let const .

    代理 作为 具有

    • has 陷阱总是会回来 true 因此,它不允许任何查找或分配超出 具有
    • get ReferenceError 尝试访问不存在的变量(即属性)时
    • set
    • target 对象没有 [[Prototype]] (即,它是用 Object.create(null)
    • 目标 对象具有 @@unscopables 属性,其值为空对象,以允许对每个属性进行范围限定

    const scope = Object.create(null)
    Object.assign(scope, {
      undefined,
      console,
      String,
      Number,
      Boolean,
      Array,
      Object,
      /* etc. */
      [Symbol.unscopables]: Object.create(null)
    })
    
    const scopeProxy = new Proxy(scope, {
      get: (obj, prop) => {
        if (prop in obj)
          return obj[prop]
        else
          throw new ReferenceError(`${prop} is not defined`)
      },
      set: Reflect.set,
      has: () => true
    })
    
    with(scopeProxy) {
      //Sandboxed code
      
      foo = Number('42')
      console.log(foo) //42
      
      try{
        console.log(scopeProxy) //Inaccessible
      }catch(e){
        console.error(e) //ReferenceError: scopeProxy is not defined
      }
    }

    避免矛盾

    MDN's page about the with statement ,但这种用法可以消除每一个。

    • 问题是:

      正在查找不是的成员的标识符 具有 语句的参数对象性能较差。

    • 任何查找都不能超出参数对象。

    • 问题是:

      很难决定,在那些同名的标识符中查找哪个标识符。

    • 所有查找和指定都检索或修改参数对象的属性。

    • 问题是:

      参数对象或其原型的属性将来可能会更改。

    • 回避:

    问题

    所以,我的问题是:

    使用这种方法还不好吗


    注: 我知道这种方法本身并不安全,可以绕过。然而,这个问题仅限于是否出于某种原因认为使用上述方法是不好的 代理 具有 组合。在这个问题上,我不关心安全性(这是一个相关但不同的问题)。

    0 回复  |  直到 4 年前
        1
  •  1
  •   ceving    5 年前

    听起来像是老好人 lexical vs dynamic scope 主题。一般来说,词法范围更安全,但在某些情况下,动态范围是有意义的,因为它大大简化了一些解决方案。我想说你的例子就是其中一个例子,在那里它可能是有用的。