了解 JS 模块模式的工作原理

Posted

技术标签:

【中文标题】了解 JS 模块模式的工作原理【英文标题】:Understanding how JS Module Pattern works 【发布时间】:2011-05-17 18:02:28 【问题描述】:

我正在尝试了解与 jQuery 一起使用的 js 模块模式。我已经对此进行了多次编辑,并将尝试为我的技能水平提供一个良好的实践(在 jquery 上几个月新鲜)。

这篇文章没有直接的问题。我更希望获得有关如何在大型网站中正确使用模块模式(连同 jquery)的反馈和意见。

更新:我添加了一堆示例,以便对所有编写方法有一个概览,并尝试涵盖所有缺陷。..

/* 
Not all browsers works with console.log, so we want to make sure that
console.log is defined. This defines the consol.log and send the messages
into an alert.
*/
if(!window.console) console = 
  log: function(s)  
    alert(s); // alert since we dont have the firebug console
  
;

// Check if namespace is defined
if (typeof (CompanyName) === 'undefined') 
    CompanyName = ;


// Or if AppName under CompanyName...

if (typeof (CompanyName.AppName) === 'undefined') 
    CompanyName.AppName = ;


// Our namespace
CompanyName.AppName = (function ($) 

    // CHAINING
    var _first = function () 
        // Important to always start with "var"
    ,

    _second = function () 
        // Chained (  ...,  ) so it doesnt need "var"
    ,

    _third = "Just a var", // Variables just ends with ,

    _four = "Another var"; // Closing the chain with ;

    var _anotherFirst = function () 
        // Previous chain of var's was ended with ; so this var needed "var" in order to start.
    ;

    g_globalVar = "I'm free!"; // When starting a var without "var", it becomes global.

    g_globalMethod = function ()  
        alert("I'm free too!"); // Global method.
    ;

    g_chainedGlobalVarOne = "We are free!",
    g_chainedGlobalVarTwo = "We are free!";

    // Private Variables
    var _privateVar = "privateVar: accessed from within AppLaunch.Admin namespace";

    // Private Methods
    var _privateMethod = function () 
       log("privateMethod: accessed only from within AppLaunch.Admin");
    ; // Last variable in a chain must always end with ; before the return 

    function log() 
        if (window.console && window.console.log)
            window.console.log('[AppName] ' + Array.prototype.join.call(arguments, ' '));
    ;

    return 
        init: function () 

            // Calling private
            _privateMethod();

            // Calling Public
            this.myPublicMethod();

            // Also Calling Public
            CompanyName.AppName.myPublicMethod();

            // Calling Other namespace's Public Method (when exists)
            CompanyName.OtherNamespace.externalPublicMethod(); 
        ,

        // Public
        myPublicMethod: function() 
            log("myPublicMethod");
        ,
        // In a View (MVC), I could have a page called myPage where I want to init
        // some particular functions. myPage can be called just like init. 
        myPage: function()  
            _second();
            _third();
        

    
)(jQuery); 

// Initialize
jQuery().ready(function() 
    CompanyName.AppName.init()
    CompanyName.AppName.myPublicMethod();
);  

试图了解正在发生的事情(随时提供更正或更好的解释):

Company.AppName = (function ($)  ...

这里创建了命名空间 Company.AppName。我在里面设置了 ($),这样我就可以使用 $ 而不会与任何其他可能使用 $ 的库发生冲突。

)(jQuery); 

据我所知,方法和变量都返回到这里的命名空间...)();通过在 () 中添加 jQuery,它会告诉它 $ 表示 jQuery。

初始化

我不确定这里的最佳做法是什么,但我会补充一下我目前所知道的。

在js文件中初始化:

jQuery(function()  
    AppLaunch.Admin.init();
);

从文件初始化:

<script type="text/javascript">
// Shorthand for jQuery(document).ready(function()  ... 

jQuery(function($)  
    AppLaunch.Admin.init($('#someSelector'));     
);
</script>

【问题讨论】:

我发现这个例子帮助很大。我进行了一些编辑,以便您可以简单地复制和粘贴 JavaScript,它无需任何调整(例如命名空间)即可工作。 【参考方案1】:

有很多地方会给你一个模块模式的深入解释; jQuery 对它的使用非常标准。

这只是众多module pattern explanations out there之一。

【讨论】:

同意,没有“jQuery 模块模式”之类的东西。如果您对它通常如何在 jquery 中使用有一个特定的问题,那对 SO 会更有用 呵呵,是的,我定义它有点错误。我的意思是一般的模块模式,但与 jQuery 一起使用。很棒的链接顺便说一句!我想我可以从中更好地理解事情的运作方式:)

以上是关于了解 JS 模块模式的工作原理的主要内容,如果未能解决你的问题,请参考以下文章

图解 WebGL & Three.js 工作原理

PHP工作原理及五大运行模式:包括cgi fast-cgicliisapiWeb模块模式

运维-了解ansible架构与工作原理

Node.js的require()的工作原理

如何去了解JavaScript引擎的工作原理

图解WebGL和Three.js工作原理