In-depth understanding of the JavaScript series (3): Fully parse module mode

Source: Internet
Author: User

Introduction Module mode is a very common mode in JavaScript programming, generally, everyone knows the basic usage, this article tries to give you more advanced usage of this mode. First, let's look at the basic features of module mode: modularity, reusable encapsulation of variables and function, and global namaspace not touching, loose coupling only exposes the method of available public, other private methods all hide about module mode, Originally by Yui's member Eric Miraglia proposed this concept 4 years ago, and we will explain the basic usage from a simple example (if you are already familiar with it, please ignore this section). Basic usage First look at the simplest implementation, the code is as follows:varCalculator =function(eq) {//You can declare a private member here    varEqctl =document.getElementById (eq); return {        //exposing members of the publicAddfunction(x, y) {varval = x +y; Eqctl.innerhtml=Val; }    };}; We can call it in the following way:varCalculator =NewCalculator (' eq ')); Calculator.add (2, 2You may see that every time you use a new one, that is, each instance in memory is a copy, if you do not need to pass parameters or some special harsh requirements, we can add a parenthesis after the last} to achieve the purpose of self-execution, So that the instance will only have a copy in memory, but before showing his merits, let's take a look at the basic use of this pattern. Anonymous closure anonymous closures are the basis for making everything possible, and this is the best feature of JavaScript, and we are creating the simplest closure function in which the code inside the function is always inside the closure, which guarantees that the internal code is private throughout the entire run-time period. (function () {    // ... All variables and functions are declared here, and scopes can only be in this anonymous closure.    // ... But the code here still has access to the external global object.} ()); Note that the parentheses behind the anonymous function, which is required by the JavaScript language, because, if you do not declare, the JavaScript interpreter defaults to declaring a function function, with parentheses, to create a functional expression, which is self-executing, Do not use the same as the above in new, of course, you can also declare: (function() {/*Internal Code*/}) (); But we recommend the first way, about function self-execution, I will have a special article to explain later, here is not much to say. Reference global variable JavaScript has an attribute called implicit global variable, regardless of whether a variable is used, the JavaScript interpreter traverses the scope chain to find the Var declaration of the entire variable, and if Var is not found, the interpreter assumes that the variable is a global variable. If the variable is used for an assignment, the interpreter will automatically create it if it is not present, which means that it is easy to use or create global variables in an anonymous closure, but the difficult thing is that the code is more difficult to manage, especially if the person reading the code looks at many of the variables that are global and local. However, fortunately in the anonymous function we can provide a relatively simple alternative, we can pass the global variable as a parameter to the anonymous function and then use, compared to the implicit global variable, it is clear and fast, we look at an example: (function($, YAHOO) {//here, our code can use the global jquery object, and so does Yahoo.} (jquery, YAHOO)), and now there are many types of libraries that use this, such as the jQuery source. However, sometimes it is possible not only to use global variables, but also to declare global variables, how to do it? We can return this global variable through the return value of the anonymous function, which is a basic module pattern, which looks at a complete code:varBlogmodule = (function () {    varmy = {}, Privatename = "Blog Park"; functionprivateaddtopic (data) {//here is the internal processing code} my. Name=Privatename; My. Addtopic=function(data) {privateaddtopic (data);    }; returnmy;} ()); The above code declares a global variable, blogmodule, with 2 accessible properties: Blogmodule.addtopic and Blogmodule.name, in addition, other code remains private in the closure of the anonymous function. We can also easily pass in other global variables according to the example of the above-mentioned global variables. Advanced usage The above content is sufficient for most users, but we can also extend a more powerful, easy-to-expand structure based on this pattern, let's look at it one by one. One limitation of the extended module pattern is that all of the code is written in one file, but in some large projects it is important to separate a feature into multiple files because it is easy to work with multiple people to develop. Looking back at the global parameter import example above, can we pass the blogmodule itself in? The answer is yes, we first pass in the Blogmodule, add a function property, and then return to achieve what we say the purpose of the code:varBlogmodule = (function(my) {My. Addphoto=function () {        //Add internal code    }; returnmy;} (Blogmodule)); Does this code seem to have a sense of how the extension method is in C #? It's a bit similar, but it's not the same. At the same time, although VAR is not a must, but to ensure consistency, we use it again, after the code is executed, the blogmodule under the Addphoto can be used, while the code inside the anonymous function still guarantees privacy and internal state. Loosely coupled extension the above code, although can be executed, but must first declare blogmodule, and then execute the above extension code, that is, the steps can not be messy, how to solve the problem? Let's recall that we usually declare variables to be like this:varCnblogs = Cnblogs | |{}; This is to ensure that the Cnblogs object is used directly at the time of existence and is directly assigned to {} When it does not exist, so let's take a look at how this feature can be used to implement arbitrary loading order of module mode:varBlogmodule = (function(my) {//Add some features        returnmy;} (Blogmodule|| {})); With this code, each separate file is guaranteed this structure, then we can implement any order of loading, so, this time the Var is must be declared, because do not declare, other files cannot read Oh. Tight coupling extension Although loose coupling extension is very bull, but there may be some limitations, such as you can not rewrite some of your properties or functions, and can not be initialized with the module's properties. Tight-coupling extensions limit the loading order, but provide an opportunity for us to reload, see the following example:varBlogmodule = (function(my) {varOldaddphotomethod =My.    Addphoto; My. Addphoto=function () {        //overloaded method, still can call old method through Oldaddphotomethod    }; returnmy;} (Blogmodule)); In this way, we achieve the purpose of overloading, of course, if you want to continue to use the original property internally, you can call Oldaddphotomethod to use. Cloning and inheritancevarBlogmodule = (function(old) {varmy ={}, key;  for(KeyinchOld ) {        if(Old.hasownproperty (key)) {My[key]=Old[key]; }    }    varOldaddphotomethod =Old .    Addphoto; My. Addphoto=function () {        //after cloning, it is rewritten, and of course it is possible to continue calling Oldaddphotomethod    }; returnmy;} (Blogmodule)); This flexibility is flexible, but it also requires a cost of flexibility, in fact, the object's Property object or function is not copied at all, just a reference to the same object, so if the old object to change it, then the object of the clone will have properties or function functions are also changed, To solve this problem, we have to use recursion, but recursion does not work well with function functions, so we eval the corresponding function in recursion. Anyway, I still put this one way in this post, people use the time to pay attention to the line. Cross file share private objects through the above example, we know that if a module is split into multiple files, each file needs to guarantee the same structure, that is, each file anonymous function in the private object can not be cross-access, then if we have to use, then what to do? Let's look at a piece of code first:varBlogmodule = (function(my) {var_private = My._private = My._private | |{}, _seal= My._seal = My._seal | |function () {            Deletemy._private; DeleteMy._seal; DeleteMy._unseal; }, _unseal= My._unseal = My._unseal | |function() {my._private=_private; My._seal=_seal; My._unseal=_unseal;            }; returnmy;} (Blogmodule||{})), any file can have properties for their local variable _private, and the settings will take effect immediately for other files. Once this module is loaded, the application calls Blogmodule._seal ()Locked, which prevents external access to the internal _private. If the module needs to proliferate again, any file can call _unseal () "Unlock" during the lifetime of the application and then load the new file. Call _seal () "Locked" again after loading. The last and simplest way to use a submodule is to create a submodule blogmodule.commentsubmodule= (function () {    varmy = {}; // ...    returnmy;} ()); Although very simple, I still put it in, because I want to explain that the sub-module also has a general module of all the advanced usage, that is, you can use any of the sub-modules of the above application methods. Summing up most of the above can be used in combination with each other, in general, if you want to design a system, you may use loosely coupled extensions, private states and sub-modules such a way. In addition, I do not mention performance issues here, but I think the module mode is efficient, the code is small, loading speed fast. Using loosely coupled extensions allows for parallel loading, which can increase download speed. However, the initialization time may be slower, but it is worthwhile to use a good pattern. Reference article: http://yuiblog.com/blog/2007/06/12/module-pattern/http//www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depthsynchronization and recommendation this article has been synchronized to the directory index: in-depth understanding of JavaScript series in-depth understanding of the JavaScript series, including the original, translation, reprint and other types of articles, if it is useful to you, please recommend supporting a, to the power of the uncle writing. 

In-depth understanding of the JavaScript series (3): Fully parse module mode

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.