【问题标题】:Can a nested function be placed in the global scope of Javascript?嵌套函数可以放在 Javascript 的全局范围内吗?
【发布时间】:2012-01-10 00:58:54
【问题描述】:

我有一种情况,我试图将几个 Javascript 文件合并为一个,并有条件地应用它们。我不想修改实际文件。有没有办法可以包装这些文件并按需调用它们?

问题是,其中一些文件中包含函数 xyz() {}。所以,用 if (false) { function xyz() {} } 包装它们会导致坏事发生。

例如,如果这是我的代码...

if (includeFile) {
    /* The file */
    function foo() {}
    /* The file */
}

问题在于 Chrome 会看到 foo() 并将其放在全局范围内 even if includeFile is false

简单的解决方案是将其修改为 var foo = function() {} 但我无法修改这些文件。

我也普遍担心在这些函数上运行 eval(),因为它们相当大。 (想想 jQuery 包装在一个函数中。如果这不是问题,那么也许 eval 就是答案?)

我希望我可以嵌套函数并将窗口作为范围传递,但是tried it on jsFiddle and it didn't seem to work

(function() {
    function foo() {
        alert('it works');
    }
}).apply(window, []);

foo();

有几个similarquestions。但是,没有人解决与我相同的情况。谢谢。

【问题讨论】:

  • 所以问题是多个文件之间存在名称冲突 - 多个函数 xyzs?修改它们真的那么糟糕吗——你担心引入错误,或者与上游保持兼容?你能机械地重命名吗,例如sed 或以某种方式使用缩小工具?
  • 我也在考虑使用缩小工具或宏预处理器。你要处理多少个xyzs?而且,如果只有部分内容要在任何给定页面上执行,那么将所有这些内容放在一个文件中真的是最好的主意吗?
  • 嗯,这个想法是根据页面和上下文,我们加载的文件太多。大约有 100 种不同的资源(包括 CSS/图像)。因此,为了减少这个数字,我们试图合并一些经常使用的文件。在这种情况下,有些是库,有些是我们的内部代码。到目前为止,我们还没有担心将函数 xyz() {} 放在全局范围内。使用新的组合文件, if (false) { function xyz() {} } 最终在全局范围内,所以我们想将它包装在 var foo = function() { function xyz() {} };如果 (假) { foo(); }

标签: javascript function scope global


【解决方案1】:

您是否考虑过使用像 require.js 这样的库?有几个库可以以更优雅的方式为您做到这一点。

如果您不想要依赖加载库,但您使用的是 jQuery 或其他类似库,则可以使用 AJAX 请求有条件地加载脚本(在 jQuery 中,您将使用 script 数据类型)。这比简单的eval() 好得多,但是当您尝试管理一系列依赖项时,它的健壮性会降低。

如果您想简单地连接所有内容,这里的另一个选项是将每个文件包装在一个匿名函数中,然后将必要的元素分配给 window 对象,将它们放在全局范围内:

(function(window) {

    /* file 1 here */
    function xyz() {
        // etc ...
    }
    /* end file 1 */

    // now selectively choose what you want to be
    // in the global scope
    window.xyz = xyz;

}(window));

xyz();

但是,这需要您做更多的工作来确定您希望在全球范围内可用的内容。请注意,有必要将 window 作为参数传递给匿名函数,但如果您要多次引用它并不是一个坏主意(这会加快引用速度并允许变量名修改在代码压缩期间)。

【讨论】:

  • 如果我们从头开始编写所有代码,这是一个很好的解决方案,但问题的主要焦点是是否可以在全局范围内显式放置嵌套函数。
  • 啊,我明白了。请查看我的编辑 - 我认为这解决了您的目标。
  • 谢谢。 That seems to work。据我所知,我认为这是我们将获得的最好成绩。我可以忍受这个,但我真的希望有某种巧妙的包装。你可以看到我希望能够做一些类似的事情 (function() { function xyz() { } }).apply(window, []);作为一个偷偷摸摸的解决方案。
  • 您的 apply 技巧仅在内部函数中设置 this 的值 - 所以您可以使用 (function() { this.xyz = function() { } }).apply(window, []) 而不是我的版本。但我的版本可能更清晰,压缩效果更好。
  • 实际上,就我不想编辑大部分文件的要求而言,您的版本也更好。在我的情况下,我宁愿在末尾添加几行而不是更改组合代码。谢谢。
猜你喜欢
  • 1970-01-01
  • 2017-01-20
  • 2012-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-23
相关资源
最近更新 更多