Deep understanding of JavaScript Series (3) Comprehensive parsing module mode _javascript techniques

Source: Internet
Author: User
Tags anonymous closure
Brief introduction
Module mode is a very common pattern in JavaScript programming, which is generally known as basic usage, and this article tries to give you more advanced usage of the pattern.
First, let's look at the basic features of module mode:
Modular, REUSABLE
Encapsulates variables and function, and does not touch the global namaspace, loosely coupled
Exposes only the methods available to public, and all other private methods are hidden
About module mode, the first is by Yui members Eric Miraglia 4 years ago, we will explain the basic usage from a simple example (if you are already very familiar, please ignore this section).
Basic usage
Let's take a look at one of the simplest implementations, with the following code:
Copy Code code as follows:

var Calculator = function (eq) {
Here you can declare a private member
var eqctl = document.getElementById (eq);
return {
Exposing members of the public
Add:function (x, y) {
var val = x + y;
eqctl.innerhtml = val;
}
};
};

We can invoke it in the following way:
Copy Code code as follows:

var calculator = new Calculator (' eq ');
Calculator.add (2, 2);

You 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 demanding requirements, we can add a bracket after the last one, to achieve the purpose of the implementation, So the instance will only have one copy in memory, but before we show off his merits, let's take a look at the basics of how to use the pattern.
Anonymous closures
Anonymous closures are the basis for making everything possible, and this is also the best feature of JavaScript, and we create the simplest closure function, where the code inside the function always exists within the closure, which ensures that the internal code is private throughout the running cycle.
Copy Code code as follows:

(function () {
// ... All the variables and functions are declared here, and the scope is only in this anonymous closure.
// ... But the code here still has access to external global objects.
}());

Note that the parentheses behind the anonymous function are required by the JavaScript language, because if you do not declare it, the JavaScript interpreter defaults to declaring a function function, with parentheses, that is, to create a function expression, which is self executing, You don't need to be in new with the above, but you can also declare:
(function () {/* Internal code */}) ();
However, we recommend the use of the first way, about the function from the implementation, I will have a special article after the detailed, here is not more to say.
Referencing global variables
JavaScript has an attribute called an implicit global variable, regardless of whether a variable has been used, the JavaScript interpreter loops through the scope chain to find the Var declaration for 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 assignment operations , if it doesn't exist before, the interpreter automatically creates it, which means it's easy to use or create a global variable in an anonymous closure, but it's harder to manage the code, especially if the person reading the code looks at a lot of things that distinguish which variables are global and which are 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:
Copy Code code as follows:

(Function ($, YAHOO) {
Here, our code can use the global jquery object, Yahoo is the same
} (JQuery, YAHOO));

Now many libraries have this use, such as jquery source.
However, sometimes it is possible to not only use global variables, but also to declare global variables. We can return this global variable through the return value of the anonymous function, which is a basic module pattern to see a complete code:
Copy Code code as follows:

var Blogmodule = (function () {
var my = {}, privatename = "blog Garden";
function Privateaddtopic (data) {
This is the internal processing code.
}
My. Name = Privatename;
My. Addtopic = function (data) {
Privateaddtopic (data);
};
return to my;
} ());

The code above declares a global variable Blogmodule with 2 accessible properties: Blogmodule.addtopic and Blogmodule.name, and other code is kept private in the closure of anonymous functions. At the same time, we can easily pass in other global variables by passing the example of the global variables above.
Advanced usage
The above content is sufficient for most users, but we can also extend a more powerful, easily scalable structure based on this pattern, let's look at it one at a.
Extended
One of the limitations of module mode is that all code is written in one file, but in some large projects it is important to separate a function into multiple files because it is easy to develop with more than one partner. Look back at the above global parameter import example, can we pass the blogmodule itself? The answer is yes, we first pass the blogmodule in, add a function property, and then return to achieve what we say, on the code:
Copy Code code as follows:

var Blogmodule = (function (my) {
My. Addphoto = function () {
Add internal code
};
return to my;
} (Blogmodule));

Does this piece of code seem to have the feeling of extending the method in C #? A bit similar, but the nature is not the same OH. While Var is not required, we use it again to ensure consistency, and after the code is executed, the Blogmodule Addphoto can be used, while the code inside the anonymous function still guarantees privacy and internal state.
Loosely coupled extensions
Although the above code can be executed, but must first declare blogmodule, and then execute the extension code above, that is, the steps can not be messy, how to solve this problem? Let's recall that we usually declare variables like this:
var cnblogs = Cnblogs | | {} ;
This is to make sure that the Cnblogs object, which is used directly in existence, is directly assigned to {} When it does not exist, and we look at how this feature can be used to implement the arbitrary loading order of the module pattern:
Copy Code code as follows:

var Blogmodule = (function (my) {
Add some features
return to my;
} (Blogmodule | | {}));

With this kind of code, each separate file guarantees this structure, then we can implement any order of loading, so, this time Var is must be declared, because it does not declare that the other files can not read Oh.
Tight coupling extension
Although loose coupling extends very well, there may be some limitations, such as the inability to rewrite some of your properties or functions, or the properties of a module when initializing. Tight-coupled extensions limit the loading order, but provide the opportunity for us to overload, looking at the following example:
Copy Code code as follows:

var Blogmodule = (function (my) {
var Oldaddphotomethod = My. Addphoto;
My. Addphoto = function () {
Overloaded method, the old method can still be invoked via Oldaddphotomethod
};
return to my;
} (Blogmodule));

In this way, we achieve the purpose of overloading, of course, if you want to continue to use the original properties inside, you can invoke Oldaddphotomethod to use.
Cloning and inheritance
Copy Code code as follows:

var Blogmodule = (function (old) {
var my = {},
Key
For (key in old) {
if (Old.hasownproperty (key)) {
My[key] = Old[key];
}
}
var Oldaddphotomethod = old. Addphoto;
My. Addphoto = function () {
After cloning, it was rewritten and, of course, you can continue to invoke Oldaddphotomethod
};
return to my;
} (Blogmodule));

Flexibility in this way is flexible, but it also takes a flexible price, in fact, the object's Property object or function is not replicated at all, just a reference to the same object, so if the old object to change it, the cloned object after the property or function functions will be changed, To solve this problem, we have to use recursion, but recursion is not good for the assignment of function functions, so we eval the corresponding function in recursion. Anyway, I still put this way in this post, we use the time to pay attention to the line.
Share private objects across files
From the example above, we know that if a module is split into multiple files, each file needs to be guaranteed the same structure, which means that private objects in each file's anonymous function cannot be interleaved, so what if we have to use them? Let's look at a piece of code first:
Copy Code code as follows:

var Blogmodule = (function (my) {
var _private = My._private = My._private | | {},
_seal = My._seal = My._seal | | function () {
Delete my._private;
Delete my._seal;
Delete my._unseal;
},
_unseal = My._unseal = My._unseal | | function () {
My._private = _private;
My._seal = _seal;
My._unseal = _unseal;
};
return to my;
} (Blogmodule | | {}));

Any file can set properties on their local variable _private, and the settings will take effect immediately for other files. Once this module is loaded, the application will call Blogmodule._seal () "lock", which will prevent external access to the internal _private. If this module needs to proliferate again, any file can invoke _unseal () "Unlock" in the application lifecycle, and then load the new file. After loading again call _seal () "Lock".
Sub Modules
The last and easiest way to use it is to create a child module
Copy Code code as follows:

Blogmodule.commentsubmodule = (function () {
var my = {};
// ...
return to my;
} ());

Even though it's very simple, I put it in because I want to show that the sub module also has all the advanced uses of the general module, which means that you can reuse some of the above application methods for any of the modules.
Summarize
Most of the above methods can be used in combination with each other, in general, if you want to design the system, you may use loose coupling extension, private state and sub modules in such a way. In addition, I do not mention performance issues here, but I think module mode is efficient, less code, faster loading. The use of loosely coupled extensions allows for parallel loading, which can improve download speed. The initialization time may be slower, but it is worthwhile to use a good pattern.
Reference articles:
http://yuiblog.com/blog/2007/06/12/module-pattern/
Http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth
Sync and Recommendation
This article has been synchronized to the directory index: Deep understanding of the JavaScript series
In-depth understanding of the JavaScript series of articles, including the original, translation, reprint and other types of articles, if useful to you, please recommend support, to the Uncle writing motivation.

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.