繁体   English   中英

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

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

例子:

var test = 'global value';

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

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

假设宿主环境未知,这意味着我们不能假设可以通过window名称访问全局对象。 此外,该函数不允许接收任何参数!

修复

var test = 'global value';

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

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

真正的解决方案是修复您的代码,这样您就不会隐藏您关心的全局变量。

评估工作

您可以随时使用全局 eval,它是最可靠的。

例子

var test = 'global value';

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

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

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

如果您不喜欢定义全局 eval,您可以使用Function间接完成

现场示例

var test = 'global value';

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

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

其他黑客

以下在非严格模式下工作

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

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

这个 hack 可以在破碎的实现中工作

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

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

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

依靠它的this作为全局对象怎么样(没有显式引用window )。

console.log(this.test);

js小提琴

您也可以使用对eval()的间接调用( execScript()用于 IE 目的,但可以随意忽略,因为您提到不假设浏览器)。

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

js小提琴

从根本上说,如果您想在严格模式代码中执行此操作,那么最大的问题是获取全局对象。 幸好有一些简单的方法: var global = (1,eval)("this"); (它不适用于所有浏览器,因为它的行为在 ES3 中未定义,尽管在 ES5 中定义)或var global = (new Function("return this"))(); (确实如此)。

所以,把它和你需要的其他东西放在一起,你可以有一个功能,比如:

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

避免每次创建函数的成本可能会更好,因此类似以下内容会更好:

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

ES2020以来,所有现代浏览器都支持globalThis。

var test = 'global value';

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

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

这取决于。 绕过“不允许接收任何参数”的“厚脸皮”方法可能是使用call

var test = 'global value';

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

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

但是,如果你能指望this是当没有全局对象this没有明确指定,然后this.test会工作。

另一种解决方案是记忆全局对象:

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