ES6类:自省呢?

塞缪尔·迈森纽夫

在ES5中,我可以检查窗口对象上是否存在“类”(构造函数):

if (window.MyClass) {
... // do something
}

根据本文在ES6中,全局声明的类是全局变量,而不是全局对象的属性(window在浏览器上为):

但是现在也有一些不是全局对象属性的全局变量。在全局范围内,以下声明创建此类变量:

  • let 声明书
  • const 声明书
  • 类声明

因此,如果我不能使用if (window.MyClass),有没有办法做到这一点?

其实有没有使用window对象的正确方法吗?

TJ人群

在ES5中,我们可以发现窗口对象上是否存在类

仅当构造函数为全局函数时,这是较差的做法。

根据本文在ES6中,全局声明的类是全局变量,而不是全局对象的属性...

正确的。全局范围内letconst声明也是如此。)这在第8.1.1.4节:全局环境记录中定义

逻辑上,全局环境记录是单个记录,但是它被指定为封装对象环境记录和声明性环境记录的复合记录。对象环境记录具有关联领域的全局对象作为其基础对象。此全局对象是全局环境记录的GetThisBinding具体方法返回的值。(例如,window浏览器上引用的全局对象— TJ) 全局环境记录的对象Environment Record组件包含所有内置全局变量的绑定(第18节)以及FunctionDeclarationGeneratorDeclarationVariableStatement引入的所有绑定包含在全局代码中。全局代码中所有其他ECMAScript声明的绑定包含在全局环境记录的声明性环境记录组件中。

(我的强调)这样用来去ES5全局对象上和早期仍然做的事情(加发电机,如果没有他们,因为那将是更加令人困惑),但新的东西(letconst,和class声明)不要它们是全局变量,而不是全局对象的属性。

回到您的问题...

因此,如果我不能使用if (window.MyClass),有没有办法做到这一点?

你可以用

if (typeof MyClass === "function") {

...因为typeof无法解析的符号不会引发ReferenceError这也具有检查MyClass代码是否在代码范围内的优点,即使它不是全局的。

有一个疑难杂症有虽然:如果代码是在相同的范围内MyClass通过声明class(或letconst),但它上面 MyClass在该范围内,即使是typeof检查将抛出ReferenceError,因为你不能访问它创建的结合(不即使有typeof)之前class(或letconst)。

例如,这将引发:

if (typeof MyClass === "function") {  // ReferenceError here
    // Yup, it's defined
    // ...
}
// ...
class MyClass {
}

从范围到开头的空间classletconst线称为颞死区(TDZ),你不能访问变量都具有约束力。因此,您必须抓住ReferenceError

let exists = false;
try {
    exists = typeof MyClass === "function";
} catch (e) {
}

其实有没有使用window对象的正确方法吗?

在JavaScript模块获得广泛的浏览器支持之前,有两种方法:

  1. 使用某种异步模块定义库来处理模块的加载。一些示例:RequireJS,SystemJS,CommonJS

  2. 有一个用于引用对象的全局变量,并使该对象的各种应用程序具有全局属性。这是一种典型的方法:

    var MyApp = MyApp || {};
    if (!MyApp.ThisModule) {                  // You can leave this `if` out
                                              // if there's no chance of the file
                                              // being loaded more than once
        MyApp.ThisModule = function(module) {
            module.MyClass = class MyClass {
                // ...class definition here...
            }
        }({});
    }
    

这也为您提供了一个方便的作用域(匿名函数),可以在其中放置任何模块级全局变量。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章