FZs*_*FZs 9 javascript with-statement es6-proxy
首先,我要澄清,我知道,with已被弃用,并使用它是通常一个糟糕的做法。
但是,我的问题是关于一个特殊情况:使用特殊Proxy对象作为with.
我正在做一个项目,我必须将一段代码的访问权限限制在全局范围内。
一种方法可能是使用 with 循环eval,它undefined为全局对象的每个属性创建具有值的常量变量,但这似乎比 using 更糟糕with,并且不能限制对使用letand创建的变量的访问const。
hastrap 总是返回true,因此它不允许任何查找或赋值超出with语句gettrap 正常运行,除了它ReferenceError在尝试访问不存在的变量(即属性)时抛出sset trap 正常运行(或者可能包含一些自定义逻辑)target对象没有[[Prototype]](即它是用创建的Object.create(null))target对象具有一个@@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
}
}Run Code Online (Sandbox Code Playgroud)
在MDN 的页面with上列出了几个关于statement的contras,但是它的这种用法摆脱了每一个。
问题:
查找不是with语句参数对象成员的标识符的性能较低。
回避:
任何查找都不能超出参数对象。
问题:
很难决定哪个标识符会在同名的标识符中查找。
回避:
所有查找和分配都会检索或修改参数对象的属性。
问题:
参数对象或其原型的属性将来可能会发生变化。
回避:
参数对象最初是空的,没有原型,因此没有属性可以改变。
上面的代码完美运行,MDN 上列出的 contras 似乎不适用于这种情况。
所以,我的问题是:
使用该with语句是否仍然是一种不好的做法,如果是,在这种特定情况下使用它有什么缺点?
注意:我知道这种方法本身并不安全,可以绕过。但是,这个问题仅限于使用上述Proxy-with组合是否出于某种原因被认为是不好的。在这个问题中,我不关心安全性(这是一个相关但不同的问题)。