模块模式 - 如何将一个模块的代码拆分成不同的js文件? [英] Module pattern- How to split the code for one module into different js files?

查看:111
本文介绍了模块模式 - 如何将一个模块的代码拆分成不同的js文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于模块模式,我做的事情如下:

For the module pattern, I'm doing something like:

(function(namespace) {
    // tons of code
    // blabla
})(window.myGlobalNamespace);

如何拆分代码?我可以想到几种方法,比如使用命名空间的层次结构,或者通过 window.myGlobalNamespace.additionalFunc = function(){// blabla} 扩展对象。还有什么其他方法?优缺点都有什么?哪一个被认为是更好的做法?

How do I split the code? I can think of a few ways, like use a hierachy of namespaces, or expand the object outside by window.myGlobalNamespace.additionalFunc = function () {//blabla}. What are the other ways? What are the pros and cons? Which one is considered better practice?

这两个答案都提出了RequireJS。你能否解释一下RequireJS如何解决这些问题:

Both of the two answers suggest RequireJS. Can you please explain how RequireJS can solve these problems:

first.js:

(function(context) {
    var parentPrivate = 'parentPrivate';
})(window.myGlobalNamespace);

second.js:

second.js:

(function(context) {
    this.childFunction = console.log('trying to access parent private field: ' + parentPriavte);
}(window.myGlobalNamespace.subNamspace);

main.js:

window.myGlobalNamespace.subNamspace.childFunction(); // doesn't work

人们可以做

window.myGlobalNamespace.subNamspace.childFunction = function() {alert("a new function");}

改变我的代码行为!

这里有两个问题:


  1. 我们不能有儿童可以访问但不能访问外部的字段公共(即受保护)。有没有办法实现这一目标?

  1. We can't have a field that's accessible by child but not to outside public (i.e. protected). Is there any way to achieve that?

如果没有,这意味着如果我们想让父母可以访问,我们需要将其公之于众。然后用户就可以修改它了!

If not, meaning if we wanteparentPrivate to be accessible, we need to make it public. Then the user will be able to modify it!

此外,所有公共功能都可以更改和替换。我不希望这种情况发生。

What's more, all the public functions can be altered and replaced. I don't want that to happen.

我不知道RequireJS如何解决这些问题。有人可以解释一下吗?

I don't see how RequireJS solves these problems. Can someone shed some light?

推荐答案

只有两种方法可以将JavaScript转换为HTML:

There are only 2 ways to get JavaScript into HTML:


  1. 内联 - < script>一些JavaScript< / script>

  2. 链接 - < script src ='main.js' >< / script>

  1. Inline - <script> some JavaScript </script>
  2. Link - <script src='main.js'></script>

我知道这很明显,但我们需要共同点接下来。 ;)

I know this is obvious but we need that common ground for what comes next. ;)

JavaScript无法将其他JavaScript文件导入其自身。所有导入都在HTML中完成。你可以通过以下几种方式做到这一点:

JavaScript does not have the ability to "import" other JavaScript files into it's self. All the "importing" is done in the HTML. You can do this several ways:


  • 链接每个单独进入HMTL

  • 通过一些JavaScript动态链接

  • Link each one individually into the HMTL
  • Dynamically link them in through some JavaScript

var script = document.createElement("script");
script.src = "all.js";
document.documentElement.firstChild.appendChild(script);


  • 图书馆,如 RequireJS 。 RequireJS使用异步模块定义(AMD)API 。它是用于定义模块的JavaScript机制,以便可以异步加载模块及其依赖项。

  • Library like RequireJS. RequireJS uses Asynchronous Module Definition (AMD) API. It is the JavaScript mechanism for defining modules such that the module and its dependencies can be asynchronously loaded.

    考虑将JavaScript分成单独文件的原因是导入的。

    It is import to consider reasons for separating JavaScript into separate files.


    • 可维护性 - 一次处理一件事变得更容易

    • 可读性 - 如果所有内容都在一个大文件中,很难看出是什么

    • 分工 - 让多个开发人员更多地工作文件而不是一个大文件

    • 重用 - 您的所有功能都可以分解为高度凝聚力的模块

    • Maintainability - it becomes easier to work on one piece at a time
    • Readability - if everything is in one big file it is very hard to see what is what
    • Division of Labor - it is easier to have multiple developers working on multiple files instead of one big one
    • Reuse - all your functions can be broken up into highly cohesive modules

    单独的JavaScript文件 DO不让事情私有,闭包会让事情变得私有。

    Separate JavaScript files DO NOT make things Private, Closures make things Private.

    现在,请考虑当天结束时所有事情都准备就绪生产你能做的最好的事情是优化您的JavaScript,将它们全部合并到一个文件中,以便用户只有一个文件可供下载。

    Now, consider at the end of the day when everything is ready for production the best thing you could do is Optimize your JavaScript by combining it all into one file so that the user only has one file to download.

    在JavaScript中处理私有变量时,您会在某些时候想要访问它们。

    When dealing with Private variables in JavaScript, you will at some point want to access them.


    • 公开功能 - 可以更改

    • 特权功能 - 可以访问私有变量的公共功能。

    • 但是,如果该功能位于实例中,则只能在每个对象中更改

    • Public function - can be altered.
    • Privileged function - a Public function that can access the Private variable.
    • However if the function is in an Instance then it can only be altered in each Object.

    让我用一些代码来说明。

    Let me illustrate with some code.

    module-test.html和main.js(合并first.js,second.js和main.js以便于测试)

    module-test.html and main.js (merged first.js, second.js, and main.js for easier testing)

    var MODULE = (function () {
    	//Private variables
    	var privateParent,
    	    app;
    	
    	privateParent = 'parentPrivate';
    	
    	return app = {
    		//Privileged method
    		getPrivateParent: function() {
    			return privateParent;
    		}
    	};
    }());
    
    MODULE.sub = (function (parentApp) {
    	//Private variables
    	var childMessage,
    	    Constr;
    	
    	childMessage = ' - trying to access parent private field: ' + parentApp.getPrivateParent();  //prints parentPrivate
    
    	Constr = function () {
    		this.childF = this.childFunction();
    	};
    	
    	//Constructor
    	Constr.prototype = {
    		constructor: MODULE.sub,
    		version: "1.0",
    		childFunction: function () {
    			$("#testing-div").append(childMessage + "</br>");
    		}
    	};
    	return Constr;
    	
    }(MODULE));
    	
    //We could just as easily print to the console, but the 'append' allows us to display the results on the page.
    
    $("#testing-div").append("This first part shows what <b>does not work</b>; everything is 'undefined'. " + "</br>");
    $("#testing-div").append("You are unable to access the var or func directly. " + "</br>");
    $("#testing-div").append("MODULE.privateParent = " + MODULE.privateParent + "</br>");
    $("#testing-div").append("MODULE.app = " + MODULE.app + "</br>");
    $("#testing-div").append("MODULE.sub.childMessage = " + MODULE.sub.childMessage + "</br>");
    $("#testing-div").append("MODULE.sub.Constr = " + MODULE.sub.Constr + "</br>");
    $("#testing-div").append("MODULE.sub.childFunction = " + MODULE.sub.childFunction + "</br>");
    $("#testing-div").append("END lesson. You must access childFunction() through the <b>new</b> operator." + "</br>");
    $("#testing-div").append("----------------------------------------------------" + "</br>");
    	
    $("#testing-div").append("Let's see if making an instance of the Object works" + "</br>");
    var test = new MODULE.sub();
    test.childFunction(); //run the method
    $("#testing-div").append("Looks like it did!!!!" + "</br>");
    $("#testing-div").append("----------------------------------------------------" + "</br>");
    	
    $("#testing-div").append("Now let's try to change the childFunction() ?" + "</br>");
    test.childFunction = function() {$("#testing-div").append(" - This is a new function." + "</br>");}
    test.childFunction(); // altered version
    $("#testing-div").append("Looks like it was changed. :(" + "</br>");
    $("#testing-div").append("----------------------------------------------------" + "</br>");
    $("#testing-div").append("Does it stay changed?" + "</br>");
    var test2 = new MODULE.sub();
    test2.childFunction(); // doesn't work
    $("#testing-div").append("NO, it was only Overriden in the 'test' Object.  It did not effect all the other new objects. :)" + "</br>");
    $("#testing-div").append("----------------------------------------------------" + "</br>");

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="ISO-8859-1">
    <title>Module Test</title>
    <!-- 	<script data-main="scripts/main" src="scripts/require.js"></script> -->
    </head>
    <body>
        <h1>This is a test for separate Modules and Private variables.</h1>
        <div id="testing-div">
        </div>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
        <script src="main.js"></script>
    </body>
    </html>

    - -

    如果你想使用RequireJS来完成上述任务,你可以。 RequireJS使用您和我已经使用的模块模式。如果你想分离文件,那么有两种方法可以做到这一点。

    If you want to use RequireJS to accomplish the above, you can. RequireJS uses the Module Pattern which is what you and I are already using. If you want to separate out the files then there are two ways to do this.


    1. 正常 - 只需设置你的JS文件使用RequireJS并只需稍加修改就可以放入上面的模块。

    2. 杠杆 - 使用RequireJS的Module特性作为要设置的模块关闭。这看起来可能更难以弄清楚,但从长远来看它可能更有效。

    1. Normal - Just set up your JS files to use RequireJS and drop in the above Modules with only a slight modification.
    2. Leveraged - Use the Module nature of RequireJS as the modules to set up the closures. This looks like it may be harder to figure out but it may be more efficient in the long run.

    注意:我还没有机会比较这两个选项,但希望将它们包括在内以保证完整性。

    您可能会发现以下参考资料有用:

    You may find the following references helpful:

    • JavaScript Module Pattern: In-Depth
    • Private Members in JavaScript

    这篇关于模块模式 - 如何将一个模块的代码拆分成不同的js文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆