ES6类:内省呢?
ES6 classes : what about instrospection?
在ES5中,我可以检查窗口对象上是否存在一个"类"(构造函数):
if (window.MyClass) {
... // do something
}
在ES6中,根据这篇文章,全局声明的类是全局的,而不是全局对象的属性(在浏览器上是window
):
但是现在也有一些全局变量不是全局对象的属性。在全局作用域中,以下声明创建了这样的变量:
let
声明- <
const
声明- 声明类/gh>
所以,如果我不能使用if (window.MyClass)
,有办法做同样的?
实际上有没有一种合适的方法来做到这一点,而不使用窗口对象
在ES5中,我们可以检测窗口对象
上是否存在类
只有在构造函数是全局的情况下,这是不好的做法。
在ES6中,根据这篇文章,全局声明的类是全局的,而不是全局对象的属性…
正确的。(let
和const
声明在全局作用域也是如此。)这在§8.1.1.4中定义:全球环境记录:
全局环境记录在逻辑上是单个记录,但它被指定为封装对象环境记录和声明性环境记录的组合。对象Environment Record将关联Realm的全局对象作为其基对象。这个全局对象是由全局环境记录的GetThisBinding具体方法返回的值。(如。,
window
在浏览器上引用的全局对象。tj) 全局环境记录的对象Environment Record组件包含所有内置全局(第18条)的绑定和由全局代码中包含的FunctionDeclaration、GeneratorDeclaration或VariableStatement引入的所有绑定。全局代码中所有其他ECMAScript声明的绑定都包含在全局环境记录的声明性环境记录组件中。
(我的重点)所以在ES5和更早的时候,全局对象上的东西仍然可以(加上生成器,因为如果它们不这样做会更令人困惑),但是新的东西(let
, const
和class
声明)不。它们是全局的,但不是全局对象的属性。
回到你的问题…
所以,如果我不能使用
if (window.MyClass)
,有办法做同样的吗?
你可以用
if (typeof MyClass === "function") {
…因为不可解析符号的typeof
不会抛出ReferenceError
。这样还可以检查MyClass
是否在代码的作用域中,即使它是不是全局的。
有一个问题:如果该代码在通过class
(或let
或const
)声明MyClass
的同一作用域中,但它在该作用域中高于 MyClass
,即使typeof
检查也会抛出ReferenceError
,因为您无法访问它在class
(或let
或const
)之前创建的的绑定(甚至与typeof
)。
。,这将抛出:
if (typeof MyClass === "function") { // ReferenceError here
// Yup, it's defined
// ...
}
// ...
class MyClass {
}
从作用域开始到class
、let
或const
行之间的空间称为时间死区 (TDZ),您根本不能访问变量绑定。因此,您必须捕获ReferenceError
:
let exists = false;
try {
exists = typeof MyClass === "function";
} catch (e) {
}
实际上有没有一种合适的方法来做到这一点,而不使用窗口对象?
在JavaScript模块得到广泛的浏览器支持之前,有几种方法:
使用某种异步模块定义库来处理模块的加载。一些例子:RequireJS, SystemJS, CommonJS
有一个全局变量,你将使用它来引用一个对象,并使该对象的各种应用程序的全局属性。下面是一个典型的方法:
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... } }({}); }
这也为您提供了一个方便的作用域(匿名函数),可以在其中放置任何模块级全局变量。
- ES6构造函数返回基类的实例
- 如何在下面的ES6循环中获得前面的文本
- es6 相当于下划线查找位置
- 如何在Javascript/ES6中的Aurelia浏览器应用程序中使用AWS S3
- ES6生成器:.next()的输入值
- 简单的ES6承诺问题-交换解决和拒绝参数
- 映射数组ES6时考虑空值
- @@(“at at”)在ES6 JavaScript中是什么意思
- 在ES6中,模块将导致多个网络调用,因为两个模块不能在单个文件中定义
- ES6是否引入了一种机制来生成块范围的函数语句(而不是表达式)
- 使用Ember-cli项目中的ES6库
- JShint-.jshintrc中的ES6有esversion,但仍收到警告(使用atom)
- 在ES6 Promise中,我应该在解决/拒绝之前使用return吗
- Unexpected Transpile ES6>ES5
- 可以合并或嵌套ES6导入
- ES6 模板文字是否比 eval 更安全
- Es6:能够在设置/更新/删除对象属性时调用自定义方法
- 数组值的排序以匹配另一个数组ES6
- 在es6中,将带有回调的事件侦听器设置为可迭代的
- ES6类:内省呢?