The essence of JavaScript module pattern

Source: Internet
Author: User

JavaScript module pattern is a common javascript encoding mode. This mode is easy to understand, but there are many advanced usage that have not been noticed yet. This article will review this design pattern and introduce some advanced usage, one of which is my original. In my project, I usually import a file containing the following JavaScript code in a jsp: var myBrand = {name: "xxx "}; var isBrand = function (brand) {return brand = "xxx"} When copying code and programming with Chen xianjun, a very senior colleague of our company, we learned: it is defined on the outermost side of all functions. variables defined using or without the var keyword are global variables. And finally merged into a js file. That is to say, defining methods and variables in this way is very dangerous and can easily pollute some global variables in other frameworks. That's why I translate this JavaScript module pattern. Some common frameworks like JQuery and Underscore adopt this modular approach. For basic usage, we will first introduce the module mode. If you are familiar with the module mode, you can directly jump to the advanced usage section. 1. Anonymous Closure This is a basic javascipt constructor and is also the best feature of javascipt. We declare an anonymous function and execute it immediately. All the code in a function lives in a closure, which makes private methods and members a reality and can only exist throughout the lifecycle of our application. (Function (){//... all vars and functions are in this scope only // still maintains access to all globals} (); note that this anonymous function is included in. This is a language requirement. If no () function is included, javasript considers this as a function declaration. Since the operators such as arc () and JS &, XOR, and comma eliminate ambiguity in function expressions and function declarations, once the interpreter knows that one of them is an expression, other expressions are also used by default. 2. The global introduction of javascipt has a feature called implicit global variables. When a variable is used, the interpreter traverses the scope chain to find the variable declared by var. If this variable is not found, it is an implicit global variable by default. At the same time, this also shows that it is very easy to create a full-board variable in an anonymous closure. Unfortunately, this method makes code very difficult to manage, because it is difficult to know which variable's declaration cycle is global. Fortunately, our anonymous functions provide a simple choice. Using global variables as parameters makes it clearer and faster to introduce global variables than our own implicit global variables. Here is an example: (function ($, YAHOO) {// now have access to globals jQuery (as $) and YAHOO in this code} (jQuery, YAHOO )); currently, many class libraries use this method, such as jQuery source code. 3. module export sometimes, if you do not want to input global variables, but want to declare some global variables, we provide a simple method to export them, and this method is the return value of anonymous functions. This is the most basic module mode. Example: var MODULE = (function () {var my = {}, privateVariable = 1; function privateMethod (){//...} my. moduleProperty = 1; my. moduleMethod = function (){//...}; return my;} (); note that we declare a global MODULE called MODULE, which contains two attributes: One member variable moduleProperty and one member method moduleMethod, it also has some private methods and attributes. We can also easily pass in the global variables that we need to pass in through the second rule. Advanced usage the above functions are very practical for our daily development, but we can design a more powerful and scalable structure based on the secondary mode. 1. Extension (Augmentation) for the module mode, the only restriction is that the code of our modules can only be declared in one file. Anyone who has worked in a large project will experience the benefits of file splitting. Fortunately, we have a very good solution to this bottleneck. First, we introduce the file where this module is located. We will introduce this module as a parameter to an anonymous immediate execution function and re-export the return value to this parameter, as shown in the following example: var MODULE = (function (my) {my. anotherMethod = function () {// added method ...}; return my;} (MODULE); here we use var to save the returned value, although this is not necessary. The new method will be added to the MODULE. This extension file can still contain some private methods and attributes. 2. Loose Augmentation: The above example requires that our modules have been defined before extension. But this is not always necessary. For JavaScript, the best way to improve the performance is to asynchronously load js files. When loading multiple files, we hope to solve the loading sequence problem, we use the following method to declare all the same modules: var MODULE = (function (my) {// add capabilities... return my;} (MODULE | {}); // This ensures that the MODULE object is directly used when it exists. If it does not exist, it is directly assigned {}, in this mode, it is necessary to use var to declare each module. Otherwise, other files cannot read this module. 3. although Tight Augmentation is great in terms of loose coupling, it can help you define the file, but it cannot help you implement the overload function, the module attributes cannot be used during module initialization. The tight mode expands the Loading Order limit and provides the overload mechanism: var MODULE = (function (my) {var old_moduleMethod = my. moduleMethod; my. moduleMethod = function () {// method override, has access to old through old_moduleMethod ...}; return my;} (MODULE); we reload the moduleMethod method, and save the original method if needed. 4. cloned from the Inheritance (Cloning and Inheritance) var MODULE_TWO = (function (old) {var my ={}, key; for (key in old) {if (old. hasOwnProperty (key) {my [key] = old [key] ;}} var super_moduleMethod = old. moduleMethod; my. moduleMethod = function () {// override method on the clone, access to super through super_moduleMethod}; return my;} (MODULE )); this mode may be the most difficult to expand. Although this design is very clever, it has paid a huge price. As I wrote, the methods or attributes of a module are not copied, but are referenced by the same object. Changing the implementation of one module also affects the other. This problem can be solved if cloning is implemented using recursion, but it is not easy to assign values to function functions using recursion. Therefore, the eval function is used in recursion. Let us know this anyway. 5. the last mode of Sub-modules is the simplest mode. We use this mode in many scenarios: MODULE. sub = (function () {var my = {};//... return my;} (); this is also one of the advanced usage of module pattern. At the same time, we can also apply some of the above patterns to submodules. Summary most advanced usage can be used in conjunction with other design patterns. If you are designing complex projects, I personally prefer three modes: loosely coupled expansion, private State, and sub-module. I did not mention performance at all here, but I would like to mention that these modes have improved the performance. Loose coupling allows parallel download and improves the download speed. Code initialization may be a little slower than the original one, but due to the reduction of global variables, the speed chain of the submodule to obtain local variables becomes shorter, and the JavaScript speed at all runtime will be significantly improved.

Related Article

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.