如何在JavaScript中检测全局变量是否已设置?

6
在 JavaScript 中,我可以使用 Object.defineProperty 来检测全局变量 foo 是否被设置(假设它最初为未定义状态)。
var foo_;
Object.defineProperty(window, 'foo', {
  get: function() {
    return foo_;
  },
  set: function(newFoo) {
    console.log('foo set to ' + newFoo);
    foo_ = newFoo;
  }
});

有没有更优雅的方法来做这件事?其中一个缺点是,我不能在同一属性上两次调用Object.defineProperty。为了检测它何时被定义,覆盖整个属性似乎有点过头了。
我能否以某种方式使用代理?我觉得我必须创建一个针对window对象的代理...那有效吗?

我认为我们可以检查它是否在window对象中可用,例如 window[foo] - techie_28
这感觉像是异步黑客。如果是的话,不要这样做。使用 Promise - 4castle
1
如果您将其用于调试,为什么不能设置两次也无关紧要呢?如果您不是用于调试,最好不要使用。 - zerkms
我正在进行调试检测,但是另一个库已经在该属性上调用了Object.defineProperty - John Hoffman
我会设置一个静态分析工具,用于记录每个未知全局变量的访问,并记录形如 window.xself['y'] 等访问表达式。它甚至可以在所有其他类型的表达式中使用 window/self/... 时记录警告。 - Tamas Hegedus
显示剩余2条评论
2个回答

1

有没有更优雅的方法来做这件事?

实际上没有。也许你可以(应该)将 _foo 隐藏在闭包中,而不是创建另一个全局变量。

唯一的问题是我不能在同一属性上两次调用 Object.defineProperty。覆盖整个属性只是为了检测它何时被定义似乎有点过度杀伐。

唯一的问题是你忘记了 传递 configurable: true 选项

我能用代理来解决吗?

不行。你不能用代理替换全局对象。唯一的方法就是将所有代码都包装在 with (new Proxy(…)) { … } 块中。


-1
你也可以这样做
var _bar;
window.__defineGetter__("bar", function(){return this._bar});
window.__defineSetter__("bar", function(v){console.log("bar set to:",v); this._bar = v;});

1
不要使用已弃用和非标准内置函数。 - Bergi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接