截取方式与属性查找/检查?

时间:2017-05-21 06:21:40

标签: javascript ecmascript-6 with-statement es6-proxy

注意:这不是关于最佳做法的问题。 with statement显然是我们在常规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一样简单,因为(我认为)引擎会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; }

但这似乎不起作用。有什么想法吗?

1 个答案:

答案 0 :(得分:0)

在撰写此问题时,我发现has的{​​{1}}陷阱是我问题的答案。所以这就是你如何实现我正在寻找的行为:

Proxy

编辑:只是注意到玩这些黑暗艺术可能会导致Chrome的DevTools crash in certain situations。以防万一节省时间调试。