【问题标题】:Javascript Modular Layout : How to call a function defined in one module from another?Javascript模块化布局:如何从另一个模块调用定义在一个模块中的函数?
【发布时间】:2011-02-26 10:37:59
【问题描述】:

以下是 javascript 应用程序的模块化布局示例。我想开始在我的工作中使用这样的结构。我正在努力弄清楚它是如何工作的,并且需要了解如何从不同的模块调用在一个模块中定义的函数?这绝对是布局 JavaScript 繁重应用程序的最佳方式吗?

window.MainModule = (function($, win, doc, undefined) {
    var modules = {};

    // -- Create as many modules as you need ...
    modules["alerter"] = (function(){
        var someFunction = function(){ alert('I alert first'); };

        return { 
            init: someFunction
        };
    }());

    modules["alerter2"] = (function(){
        var someFunction = function(){ alert('I alert second'); };

        return { 
            init: someFunction
        };
    }());

    return { 
        init: function(){
            for (var key in modules){
                modules[key].init();
            }
        }
    };
}(jQuery, this, document));

$(window.MainModule.init);

【问题讨论】:

  • 您应该考虑阅读“JavaScript:权威指南,第 5 版”的第 10 章“模块和命名空间”。
  • 太。这是一个可怕的模式。在包装器内定义模块,启动所有模块。没有办法从外部添加/删除模块,没有办法决定运行什么,不运行什么......这很愚蠢。更不用说多余的自执行功能了。使代码在语义上看起来模块化并不是模块化的......
  • @BGerrissen 所以任何帮助将不胜感激......
  • 看看requirejs.org 并拥抱异步/响应/模块化编程;)

标签: javascript web-applications module


【解决方案1】:

RequireJS 的模块化:

module1.js

define( ["dependency"] , function( dep ){

   return {
      speak: function(){
          alert( dep.message );
      }
   }

} );

dependency.js

define( {
    message: "Hello world!"
} );

impl.js

if ( $(".someCssExpression").length ) {
    require( [ "module1" ] , function( mod ){

        mod.speak();

    });
}

index.html

...

<script src="require.js" data-main="impl"></script>

...

您的文件结构将是模块化的。 您的实现将是模块化的。 并且没有笨拙的命名空间或奇怪的结构来让它感觉井井有条。

需要一些时间来适应,但完全值得。

另请阅读:

【讨论】:

  • 谢谢我这个周末自学 requireJS 来彻底解决这个问题。慢慢来!在这样一个自以为是的主题中很难得到正确的答案,但我相信 requireJS 在模块化布局方面为您做了很多工作。如果我错了,请纠正我...
【解决方案2】:

为了访问任何内容,它需要在您调用的范围内可用。 “模块”——或任何封装方法——在 JS 中总是意味着“功能”。模块只是一个匿名(未命名)函数。因此,要从函数 A 内部访问另一个函数 B(模块)中定义的元素,它要么必须在 GLOBAL SCOPE 中可用(在浏览器中:窗口对象),要么必须以其他方式获得访问权限,例如通过某些函数调用收到引用。 YUI3 ([http://developer.yahoo.com/yui/3/]) 是后者的一个有趣的例子,你的应用程序在全局范围内没有任何可用的(我认为 YUI3 是迄今为止最好的 JS 框架之一对于 SERIOUS softwarfe 开发,也一定要查看http://developer.yahoo.com/yui/theater/,尤其是来自 Javascript 之神 Douglas Crockford 的任何视频(而且我通常不会给出这类声明)。 对于 Javascript,您必须记住的是,编译器在诸如 C 之类的语言中完成的部分工作现在发生在运行时。对于诸如返回函数的立即函数调用(通过使用闭包导致封装)之类的事情,您应该记住该代码在加载期间只运行一次,但在运行时执行完全不同的代码 - 这取决于加载时代码执行的内容做了。

在您的示例中,window.MainModule=... 之后的函数在加载 JS 代码时执行。请注意,window.MainModule 并不指向那个功能!!! 相反,正如我所说,该函数在加载时执行,并将 RESULT 分配给 window.MainModule。结果是什么?好吧,只有一个 return 语句,它返回一个对象,并且该对象只有一个属性“init”,它指向一个匿名函数。

不过,在返回该对象之前,该函数会在其本地范围内创建一个变量“modules”,它指向一个对象。该对象有两个属性,这些属性被分配函数的方式与 window.MainModule 被分配一个的方式相同,因此您总共拥有三个闭包。

所以加载后你有一个全局变量

window.MainModule = { 初始化:函数(){...}

所以加载后你有一个全局变量

window.MainModule = { 初始化:函数(){...} }

在该函数执行的最后一行。

}

在该函数执行的最后一行。

虽然这个例子没有多大意义,因为你并没有真正封装任何东西。您使用双指针使私有函数可用:从 init 到局部变量 someFunction,没有任何东西是隐藏的。查看上面的 URL (Yahoo Developer Theater) 以获得更好的示例和非常详尽的解释。即使您从未接触过 YUI3,也必须观看 - 特别是 D. Crockford 的视频是一般的 JS 知识。

【讨论】:

    【解决方案3】:

    嗯嗯.. 这一切都取决于您对应用程序的需求。 只要你触摸 gui,我建议坚持使用 jQuery 插件。

    您可以使用像 yahoo 这样的命名空间模式,并为您的 申请。

    您可能不需要像在实例化主模块时那样在每个页面上运行您的模块(除非您在网站的每个页面中都有一个小部件,否则没有意义)。

    在您完成将您需要的所有操作从 javascript 抽象为函数和模块后,构建一个模块,该模块将根据每个页面/操作/无论何时需要它来加载逻辑。

    顺便说一句,你总是可以使用 mootools 开发 OO 风格,这真的是无穷无尽的。 这一切都归结为您的应用需求

    真的建议您观看 Douglas Crockford 的一些讲座(如我之前所述),here 是一篇关于模块的好文章,可以帮助您进一步理解它。 祝你好运!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-06-21
      • 1970-01-01
      • 1970-01-01
      • 2016-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-31
      相关资源
      最近更新 更多