注意:这不是关于最佳实践的问题。该with
声明显然是我们在常规 JS 使用中应该避免的。我对它的行为很感兴趣,因为我正在编写一个简单的DSL,并了解如何突破 JavaScript 的限制以使某些功能发挥作用。
考虑以下代码:
var obj = {prop:0};
with(obj) { prop = 1; }
// obj.prop === 1
每当我们在块中使用变量时with
(如prop
上面的),它首先查看该变量是否是obj
. 如果是,那么它基本上将该变量转换为obj.prop
.
但是,如果在 中找不到变量obj
,则 JS 引擎会在作用域链上冲浪,prop
直到它到达全局对象作为最后的手段:
var obj = {};
with(obj) { prop = 1; }
// obj.prop === undefined
// window.prop === 1
这是我的问题:在上面的示例中,JS 引擎prop
在obj
. 有没有办法拦截这个查找?我想“欺骗” JS 引擎(当然,以符合规范的方式)认为obj
每个属性都存在,以便with
语句中引用的所有变量都被解释为obj.variable
. 基本上,我想要这种行为:
var obj = {};
with(obj) { prop = 1; }
// obj.prop === 1
我认为这就像代理obj
和拦截get
s 一样简单,因为(我认为)引擎会执行 aget
查看 is obj
has prop
。我认为我可以简单地返回除 之外的其他内容undefined
,然后with
将obj
视为具有所有属性:
var prox = new Proxy({}, {
set(target, property, value) { target[property] = value; },
get(target, property) { return target[property] !== undefined ? target[property] : null; },
});
with(prox) { prop = 1; }
但这似乎不起作用。有任何想法吗?