首先,
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
,但这种用法可以消除每一个。
-
问题是:
很难决定,在那些同名的标识符中查找哪个标识符。
-
所有查找和指定都检索或修改参数对象的属性。
-
问题是:
参数对象或其原型的属性将来可能会更改。
-
回避:
问题
所以,我的问题是:
使用这种方法还不好吗
注:
我知道这种方法本身并不安全,可以绕过。然而,这个问题仅限于是否出于某种原因认为使用上述方法是不好的
代理
具有
组合。在这个问题上,我不关心安全性(这是一个相关但不同的问题)。