注意:这不是一个关于最佳实践的问题。 with
statement显然这是我们在常规 JS 使用中应该避免的事情。我对其行为感兴趣,因为我正在编写一个简单的 DSL并了解如何突破 JavaScript 的限制以使某些功能发挥作用。
考虑以下代码:
var obj = {prop:0};
with(obj) { prop = 1; }
// obj.prop === 1
每当我们在 with
block 中使用变量(如上面的 prop
)时,它首先会查看该变量是否是 obj< 的属性
。如果是,那么它基本上将该变量转换为 obj.prop 。
但是,如果在 obj
中找不到该变量,则 JS 引擎会在作用域链中向上查找 prop
,直到到达全局对象(作为最后的手段) :
var obj = {};
with(obj) { prop = 1; }
// obj.prop === undefined
// window.prop === 1
这是我的问题:在上面的示例中,JS 引擎在 obj
中查找 prop
。有没有办法拦截这个查找?我想“欺骗”JS 引擎(当然,以符合规范的方式)认为 obj
具有现有的所有属性,以便所有变量都通过 with 进行引用
语句被解释为 obj.variable
。基本上,我想要这种行为:
var obj = {};
with(obj) { prop = 1; }
// obj.prop === 1
我认为这就像代理 obj
和拦截 get
一样简单,因为(我认为)引擎会执行 get
看到的是 obj
有 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; }
但这似乎不起作用。有什么想法吗?
最佳答案
在写这个问题时,我发现了代理
的has
陷阱,这是我问题的答案。因此,您可以通过以下方式实现我正在寻找的行为:
var prox = new Proxy({}, {
has(target, property) { return true; },
});
with(prox) { prop = 1; }
// prox.prop === 1
编辑:请注意,玩弄这些黑暗艺术可能会导致 Chrome 的 DevTools crash in certain situations 。以防万一可以节省任何人的调试时间。
关于javascript - 拦截属性查找/检查的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44093805/