【问题标题】:Way to intercept with's property lookup/check?拦截属性查找/检查的方法?
【发布时间】:2017-10-20 23:40:13
【问题描述】:

注意:这不是关于最佳做法的问题。 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 引擎在obj 中查找prop。有没有办法拦截这个查找?我想“欺骗” JS 引擎(当然是以符合规范的方式)认为obj 具有存在的所有属性,因此所有带有with 语句的变量引用都被解释为@987654337 @。基本上,我想要这种行为:

var obj = {};
with(obj) { prop = 1; }
// obj.prop === 1

我认为这就像代理obj 和拦截gets 一样简单,因为(我认为)引擎会执行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; }

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

【问题讨论】:

  • 所以你真的没有问题吗?
  • 我有一个问题和一个答案;)
  • 看看this

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


【解决方案1】:

在写这个问题时,我发现了Proxyhas 陷阱,这是我问题的答案。所以这里是你如何实现我正在寻找的行为:

var prox = new Proxy({}, {
    has(target, property) { return true; },
});
with(prox) { prop = 1; }
// prox.prop === 1

编辑:请注意,玩弄这些黑暗艺术可能会导致 Chrome 的 DevTools crash in certain situations。以防万一这样可以节省任何人调试的时间。

【讨论】:

猜你喜欢
  • 2015-04-29
  • 2015-05-11
  • 1970-01-01
  • 2023-03-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多