简体   繁体   English

如何检索阴影全局变量的值?

[英]How to retrieve the value of a shadowed global variable?

Example:例子:

var test = 'global value';

(function() {
    var test = 'local value';

    // how to get the 'global value' string
})();

Given the condition that the host environment is unknown, meaning that we cannot assume that the global object will be accessible via the window name.假设宿主环境未知,这意味着我们不能假设可以通过window名称访问全局对象。 Also, the function is not allowed to receive any arguments!此外,该函数不允许接收任何参数!

The fix修复

var test = 'global value';

(function() {
    var test2 = 'local value';

    console.log(test);
})();

The real solution is to fix your code so your not shadowing global variables you care about.真正的解决方案是修复您的代码,这样您就不会隐藏您关心的全局变量。

Eval work around评估工作

You can always use global eval, it's the most reliable.您可以随时使用全局 eval,它是最可靠的。

Example例子

var test = 'global value';

function runEval(str) {
  return eval(str);
}

(function() {
    var test = 'local value';

    console.log(runEval("test"));
})();

If you don't like defining a global eval you can use Function to do it indirectly如果您不喜欢定义全局 eval,您可以使用Function间接完成

Live Example现场示例

var test = 'global value';

(function() {
    var test = 'local value';

    console.log(new Function ("return test;") () );
})();

Miscellaneous hacks其他黑客

The following works in non strict mode以下在非严格模式下工作

(function () {
  var test = "shadowed";

  console.log(this !== undefined && this.test);
})();

And this hack works in broken implementations这个 hack 可以在破碎的实现中工作

(function() {
    var test = 'local value';

    try { delete test; } catch (e) { }

    console.log(test);
})();

What about relying on its this as the global object (no explicit reference to window ).依靠它的this作为全局对象怎么样(没有显式引用window )。

console.log(this.test);

jsFiddle . js小提琴

You could also use an indirect call to eval() ( execScript() is here for IE purposes, but feel free to ignore as you mentioned to not assume a browser).您也可以使用对eval()的间接调用( execScript()用于 IE 目的,但可以随意忽略,因为您提到不假设浏览器)。

console.log((window.execScript || eval)('test'));

jsFiddle . js小提琴

Fundamentally the big issue, if you want to do this in strict-mode code, is getting the global object.从根本上说,如果您想在严格模式代码中执行此操作,那么最大的问题是获取全局对象。 Thankfully there are some simple ways: var global = (1,eval)("this");幸好有一些简单的方法: var global = (1,eval)("this"); (which doesn't work in every browser, as its behaviour is undefined in ES3, though defined in ES5) or var global = (new Function("return this"))(); (它不适用于所有浏览器,因为它的行为在 ES3 中未定义,尽管在 ES5 中定义)或var global = (new Function("return this"))(); (which does). (确实如此)。

So, put that together with what else you need, you can have a function such as:所以,把它和你需要的其他东西放在一起,你可以有一个功能,比如:

function getGlobal(name) {
  "use strict";
  var global = (new Function("return this"))();
  return global[name];
}

It'd probably be better to avoid the cost of creating a function each time, so something like the following would be better:避免每次创建函数的成本可能会更好,因此类似以下内容会更好:

var getGlobal = (function() {
  "use strict";
  var global = (new Function("return this"))();
  return function(name) {
    return global[name];
  }
})();

There is globalThis since ES2020, supported by all modern browsers.ES2020以来,所有现代浏览器都支持globalThis。

var test = 'global value';

(function() {
    var test = 'local value';

    console.log(globalThis.test); // 'global value'
})();

It depends.这取决于。 A "cheeky" way to get past the "not allowed to receive any arguments" might be to use call :绕过“不允许接收任何参数”的“厚脸皮”方法可能是使用call

var test = 'global value';

(function() {
    var test = 'local value';

    var globalTest = this.test;
}).call(this);

But if you can count on this being the global object when no this is explicitly specified, then this.test will work.但是,如果你能指望this是当没有全局对象this没有明确指定,然后this.test会工作。

Another solution is to memoize the global object:另一种解决方案是记忆全局对象:

var test = "global";
function called() {
    var test = "local";
    alert(arguments.callee.window.test); // alerts "global"
}
called.window = this;
called();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM