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

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

问题描述

我遇到一个有趣的问题,至少我认为这很有趣,有点恼人。我有一个课程,对于这个问题我会保持它非常简单...

  class Foo {
static pageChange (){
console.log('页面更改');
}
}

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

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

);

现在,将创建桌面和所有好东西。问题是在JavaScript中的Foo类中访问该静态方法。在此之前创建Foo之前​​就是这样的。

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

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

  for(var i = 0,l = events.length; i< l; i ++){
窗口[events.className] [events.fnName]。适用();
}

,这可以正常工作,因为Foo可以通过窗口['Foo ]
但是当您使用第一个代码片段中显示的类定义时,您将无法再从窗口超级全局访问它,只会输出'undefined'。



那么,有没有办法通过动态引用来访问类中的静态方法,就像你可以通过窗口全局的Foo对象一样?



I我希望这是正确的,我正在解释它。如果没有任何意义,请随时问问,我会尽力解释。谢谢你提前给予任何帮助。

解决方案

要获取窗口对象,你需要明确地这样做:

  window.Foo = class Foo { 。} 

阅读更多关于不属于窗口的属性的类对象在这个答案,也引用了 ECMA2015规范,第8.1.1.4节:全球环境记录


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




使用专用对象



最好不要为此使用全局对象,并将特定对象专用于包含您的类,并将该事件管理库作为基础对象,如这个简化的代码片段所示:



 (function() 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] [e vent.fnName]。适用(); }}());  


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');
    }
}

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'
        )
);

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();
}

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'.

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.

解决方案

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

window.Foo = class Foo { ... }

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:

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天全站免登陆