2015-02-10 91 views
2

我主要的应用程序基于JavaScript的“页”上的文件加载访问:调用JavaScript函数从动态加载的内部函数

var AdminConsole = (function() { 
    function openPage(folder, template) { 
     $.getScript('viewmodels/' + template + '.js') 
      .done(function() { 
       console.log(template + " script loaded."); 
      }); 
    } 
    function test() { 
     // do something ... 
    } 
})(); 

的JavaScript在$.getScript()加载看起来是这样的:

var UserPermissions = (function() { 
    // try to call test() 
})(); 

我问题是,如何从UserPermissions()内拨打AdminConsole.test()

当我尝试AdminConsole.test()它说AdminConsole是未定义的。当我尝试test()时,测试是未定义的。

+0

定义AdminConsole gloablly。 – void 2015-02-10 20:29:07

回答

4

分配给AdminConsole的值是该匿名函数返回的值。既然你什么都不回来,那就是undefined

相反,你应该导出的公共方法/属性:

var AdminConsole = (function() { 
    // ... (private data) 
    return { // Export public data to the outside 
     test: test, 
     openPage: openPage 
    }; 
})(); 

如果你不需要的私人数据,你也可以考虑简单

var AdminConsole = { 
    test: function(){ /*...*/ }, 
    openPage: function(){ /*...*/ } 
}; 
1

AdminConsole似乎是调用函数的结果。如果该功能没有return,则AdminConsole将不确定。 也许你想这样的:

AdminConsole = { 
    openPage: ... 
    test: ... 
} 

但你可能想要的是使用的模块,如Browserify或​​提供。

1

在你的代码片段中,AdminConsole是一个自动执行的匿名函数。换句话说,它等于(function() {/* your code*/})()返回的结果。在你上面的例子中,你不会返回任何东西(你只是在匿名函数中有函数),所以AdminConsole == undefined。这些功能是私人的。例如,

function myPrivateData() { 
    this.data = "public"; 
    var nobodyCanSee = "private"; 
} 
var test = new myPrivateData(); 
// test.data => "public" 
// test.nobodyCanSee => undefined 

这与您的情况相同。您的内部函数都不会附加到匿名函数,因此它们在该函数的范围之外是不可见的。

如果你想内AdminConsole访问的功能,你可以把它的对象:

var adminConsole = { 
    openPage: function() { 
     // etc 
    }, 
    test: function() { 
     // etc 
    } 
} 

采用这种结构,可以调用testadminConsole.test()

+0

我没有看到关闭与此有什么关系。看起来事情只是没有被定义为OP的预期。 – 2015-02-10 20:32:59

+0

这里涉及“a”闭包,但它不是问题或问题的焦点。 – 2015-02-10 20:36:25

+0

@JonSurrell我的意思是,它与范围有关,但我可以删除第一句。 – royhowie 2015-02-10 20:38:56