【问题标题】:JavaScript Factory class throws errors if function name is not a 'constructed string'如果函数名不是“构造字符串”,JavaScript Factory 类会抛出错误
【发布时间】:2012-09-30 20:48:57
【问题描述】:

我有一个工厂类,我在 JavaScript 中使用它通过 AJAX 动态加载类文件,然后返回一个对象。我在系统中遇到了一个非常特殊的错误,虽然它会在每个浏览器中引发错误,但在我无法解释的情况下。

这是我的 Factory 类的简化版本(我删除了很多类型检查和错误处理以将其减少到最低限度)。

function Factory(){
    // This holds which files have already been loaded
    var loaded=new Object();

    // Returns a new object
    this.getObject=function(className,methodName,methodData){

        if(loadFile('class.'+className+'.js')){

            // Making sure that the object name is defined
            if(window[className]!=null){

                // Has to be an object
                if(typeof(window[className])=='function'){

                    // Creating a temporary object
                    return new window[className];
                }
            }
        }
    }
    // Loads a file over AJAX
    var loadFile=function(address){

        // Loads as long as the file has not already been loaded
        if(loaded[address]==null){

            // Required for AJAX connections (without ASYNC)
            var XMLHttp=new XMLHttpRequest();
            XMLHttp.open('GET',address,false);
            XMLHttp.send(null);

            // Result based on response status
            if(XMLHttp.status===200 || XMLHttp.status===304){

                // Getting the contents of the script
                var data=XMLHttp.responseText;

                // Loading the script contents to the browser
                (window.execScript || function(data){
                    window['eval'].call(window,data);
                })(data);

                // makes sure that file is loaded only once
                loaded[address]=true;
            }
        }
    }

这是用户所做的:

 var Factory=new Factory();
 var alpha=Factory.getObject('example');
 alpha.set(32);
 alpha.get();
 var beta=Factory.getObject('example');
 beta.set(64);
 alpha.get();
 beta.get();

这失败了,当函数第二次运行时(在return new window[className]; 行),它说“对象不是函数”。我明白如果我在这里遗漏了什么,但这是踢球者:

如果我在我的 window[] 呼叫中添加 className 前缀,那么它可以工作。例如,如果我将我的'example' 类文件名更改为'test_example',然后有这些行:

... if(window['test_'+className]!=null){ ...
... if(typeof(window['test_'+className])=='function'){ ...
... return new window['test_'+className]; ...

然后它就可以正常工作,并且 alpha 和 beta 对象都按预期工作。当我纯粹通过变量引用它们时,它们会失败。我尝试了 className.toString() 之类的方法但没有成功,甚至失败了:

className+''

这真的很奇怪,我不知道该在哪里寻找和尝试什么,有人知道为什么会这样吗?

编辑:这是正在加载的“example.js”脚本的示例:

function example(){

    var myVar=16;

    this.set=function(value){
        myVar=value;
    }

    this.get=function(){
        alert(myVar);
    }

}

(如果我将其重命名为 test_example() 并使用构造字符串加载如上所示的函数,那么它再次起作用)

【问题讨论】:

  • 你能发布一个正在加载的文件的样本吗?
  • 您似乎在某处覆盖了window.examplewindow 是 javascript 中的全局作用域
  • @MattWhipple,添加了示例文件。
  • @JanDvorak 但我不是,脚本中没有其他内容。该示例仅在我在加载它时构造字符串时才有效,无论我如何命名它。如果我把它写成“'exa'+name”并且有 Factory.getObject('mple') 那么它也可以工作。但是当它只是一个未修改的变量时,它就会失败。
  • 无法看到它是如何因为重复使用的字符串而失败的。如果你确实构造了字符串,它是重用加载的类还是每次都获取一个新的类?

标签: javascript exception object factory dynamic-loading


【解决方案1】:

我发现了错误在哪里,而我上面的精简版本没有显示。显然我将我的新变量命名为与类本身的名称相同,因此在第一次初始化后它被覆盖了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-12
    • 1970-01-01
    • 2013-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多