Javascript ES6 类定义在窗口全局中不可访问 [英] Javascript ES6 class definition not accessible in window global

查看:59
本文介绍了Javascript ES6 类定义在窗口全局中不可访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遇到了一个有趣的问题,至少我觉得它很有趣,而且有点烦人.我有一堂课,对于这个问题,我会保持非常简单...

I have come across an interesting issue, at least I think it's interesting, and a little annoying. I have a class, for this question I will keep it extremely simple...

class Foo {
    static pageChange() {
        console.log('The page changed');
    }
}

现在,我可以使用 Foo.pageChange() 访问它,没问题,一切都按预期工作.当我尝试动态访问它时,困难的部分和有趣的部分出现了.我有一个单独的对象来监视事件并根据需要处理它们的调度.这与 Google 可视化库有关,我在其中有一个表,并且该表具有与之相关的事件.我有一个对象负责从 PHP 输出创建所有这些.这是一个非常棒的系统,简单来说,你可以在 PHP 中做这样的事情......

Now, I can access that with Foo.pageChange() no problem, everything works as expected. The hard part, and interesting bit comes in when I try to access this dynamically. I have a separate object that monitors events and handles dispatching them as needed. This pertains to the Google visualization library, where I have a table, and the table has events tied to it. I have an object that is responsible for creating all of this from PHP output. It is one heck of a system, in an easy explanation you can do something like this in PHP...

GoogleVisLibrary::renderChart(
    array(
        'chartType' => 'table',
        'chartData' => $this->chartData,
        'chartOptions' => $this-chartOptions,
        'events' => array(
             'sort' => 'Foo.pageChange'
        )
);

现在将创建表和所有好东西.问题是在 javascript 中访问 Foo 类中的静态方法.在创建 Foo 作为一个类之前,我所拥有的是这个.

now that will create teh table and all that good stuff. The problem is accessing that static method in the Foo class in javascript. What I had prior to creating the Foo as a class was this.

var Foo = {
    pageChange: function() {
         console.log('page changed');
    }
}

然后在我的事件库处理程序中,它看起来像这样..

then in my event library handler thingy it would look something like this..

for(var i = 0, l = events.length; i < l; i++) {
    window[events.className][events.fnName].apply();
}

这样就可以了,因为可以通过 window['Foo'] 访问 Foo但是当您使用第一个代码片段中显示的类定义时,您将无法再从窗口超级全局访问它,它只会输出未定义".

and that would work fine because Foo can be accessed through window['Foo'] but when you use the class definition shown in the first code snippet, you can no longer access it from the window super global, it just outputs 'undefined'.

那么,有没有什么方法可以通过动态引用访问类中的静态方法,就像您可以通过 window 全局访问 Foo 对象一样?

So, is there any way to access a static method in a class, through a dynamic reference like you can with the Foo object through the window global?

我希望这是有道理的,而且我的解释是正确的.如果任何事情没有意义,请随时提问,我会尽量解释得更好.预先感谢您提供的任何帮助.

I am hoping that makes sense and I am explaining it correctly. If anyhting doesn't make sense please feel free to ask, I will try to explain better. Thank you in advance for any help you can give.

推荐答案

要获得对 window 对象的引用,您需要明确地这样做:

To get a reference on the window object, you'll need to do that explicitly:

window.Foo = class Foo { ... }

这个答案中阅读更多关于类不是 window 对象的属性的信息,其中还引用了 ECMA2015 规范第 8.1 节.1.4:全球环境记录:

Read more about classes not being properties of the window object in this answer, which also quotes the ECMA2015 Specification, Section 8.1.1.4: Global Environment Records:

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

A global Environment Record is logically a single record but it is specified as a composite encapsulating an object Environment Record and a declarative Environment Record. The object Environment Record has as its base object the global object of the associated Realm. This global object is the value returned by the global Environment Record’s GetThisBinding concrete method. (E.g., the global object referenced by window on browsers — T.J.) The object Environment Record component of a global Environment Record contains the bindings for all built-in globals (clause 18) and all bindings introduced by a FunctionDeclaration, GeneratorDeclaration, or VariableStatement contained in global code. The bindings for all other ECMAScript declarations in global code are contained in the declarative Environment Record component of the global Environment Record.

使用专用对象

最好不要为此使用全局对象,而是专门使用一个特定对象来包含您的类并将您的事件管理库基于该对象,如以下简化片段所示:

Using a dedicated object

It would be better not to use the global object for this, and dedicate a specific object to contain your classes and base your event managing library on that object, as illustrated in this simplified snippet:

(function () {
    var classes = {
        Foo: class Foo {
            static pageChange() {
                console.log('The page changed');
            }
        }
    }

    /////////////
    var events = [{
        className: 'Foo',
        fnName: 'pageChange'
    }];
    for(var event of events) {
        classes[event.className][event.fnName].apply();
    }
}());

这篇关于Javascript ES6 类定义在窗口全局中不可访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆