【问题标题】:Javascript ES6 reference a variable in the global scope but not in the window scopeJavascript ES6 在全局范围内引用变量,但不在窗口范围内
【发布时间】:2017-09-26 03:00:16
【问题描述】:

我正在将我的代码从 ES5 升级到 ES6。在 ES5 中,我通过创建一个新脚本来动态加载函数,然后异步加载文件。代码如下:

loadClass : function(className) {
    if(typeof window[className] !== "function") {
        page.getCode(className, dirName);
        return;
    } ...


getCode(className) {
    var fileName = className.toLowerCase();
    var newScript = document.createElement('script');
    newScript.setAttribute("type", "text/javascript");
    newScript.setAttribute("src", '/public/js/' + fileName + '.js');
    var parmArr = [className];
    newScript.addEventListener('load', this.loadClass.bind("", parmArr));
    document.getElementsByTagName("head")[0].appendChild(newScript);
    return;
}

在 ES5 中,函数在全局范围内加载,在本例中为窗口。我有一个字符串中的函数/类名,我可以使用 window[classname] 引用该类,如上面的代码所示。在 ES6 中,我将调用函数和被调用函数更改为一个类。现在,当它加载脚本时,它在全局范围内作为 Myclass function() 存在,但不在窗口范围内,如 Chrome 调试器中所示:

Myclass ()
[[Scopes]] : Scopes[2]
    0 : Script
        Myclass () : () 

我不能再用一个变量作为 window[classname] 来引用它。抓住稻草我还尝试了 [classname]、global[classname] 和 Global[classname] 以及 this[classname] 和 script[classname] 但这不起作用。

在 ES6 中,当类名在变量中时,如何测试它是否已经加载?这可能是一件很容易的事情,但它让我无法理解。

提前致谢

【问题讨论】:

  • 如果你的意思是它是一个真正的 ES6 类,那么你唯一的选择就是eval。既然你是负责加载类的人,难道你不能在一个单独的对象中跟踪加载的值吗?
  • @loganfsmyth:是的,好点。当我在 PHP 中加载自己的类时,我会跟踪数组中加载的类。我还需要为 js 创建一个加载器类。 eval 确实有效,但必须包含在 try/catch 中,因为它会出错。谢谢。
  • @loganfsmyth:哎呀,即使我创建了一个加载器类并将名称添加到加载后的数组中,我仍然必须能够使用变量名测试该类是否存在。在 PHP 中有一个函数 class_exists,但在 JS 中似乎没有类似的功能。我尝试了 instanceof 并测试了类方法,但这似乎也不起作用。到目前为止,只有包含在 try/catch 中的 eval 有效,但使用 eval 似乎是一个笨拙的修复。谢谢
  • 这是一个笨拙的修复,因为这种加载东西的方法不是一个好主意:) 除非你真的想自己维护这一切,否则我建议你研究 Webpack。将内容加载到全局范围不是一个好主意,因此没有太多理由让它变得容易。
  • @loganfsmyth:到目前为止,感谢您的想法。我确实想自己维护这一点。你提到这种方法不是一个好主意。是否有另一种方法可以将文件中的类动态加载到浏览器中?我确实有一个动态加载器,但它也使用 eval 来解析文件,所以这也是不可取的。你推荐什么方法?提前致谢。

标签: javascript scope ecmascript-6 window global


【解决方案1】:

这就是 ES6 的工作原理...为了避免污染全局对象(此处为 window),您的 JavaScript 代码不再创建全局属性(除非您是明确的)。在 ES5 中,这些属性是在全局范围内使用 varfunction 时自动创建的。使用letconstclass,什么都不会发生。考虑这个例子:

// ES5

var foo;

function qux() {}

console.log('foo' in window); // true
console.log('qux' in window); // true

// ES6

let bar;
const baz = '';

class Quux {}

console.log('bar' in window); // false
console.log('baz' in window); // false
console.log('Quux' in window); // false

window.bar = bar;
window.baz = baz;
window.Quux = Quux;

console.log('bar' in window); // true
console.log('baz' in window); // true
console.log('Quux' in window); // true

【讨论】:

  • 所以你是说它做不到?如果类名在字符串中,则无法检查类是否存在?
  • 我只是想检查一下你所说的是否可以做到,并且可以!如果你这样做:window.foo = new foo()。如果你这样做:console.log('foo' in window) 它返回 true :-)
猜你喜欢
  • 2018-04-03
  • 1970-01-01
  • 2021-10-04
  • 1970-01-01
  • 2016-11-13
  • 1970-01-01
  • 1970-01-01
  • 2013-11-06
  • 1970-01-01
相关资源
最近更新 更多