JavaScript module mode programming deep analysis _javascript skills

Source: Internet
Author: User
Tags closure

Basic knowledge

First of all we need to know about module mode (2007 by Yui's Ericmiraglia in the blog), if you are familiar with Module mode, you can skip this section, directly read "Advanced mode."

anonymous function closures

Anonymous function closures are one of the best features of JavaScript, none of which makes everything possible. Now let's create an anonymous function and execute it immediately. All the code in a function is executed in a closure that determines the privacy and state of the code throughout the execution process.

Copy Code code as follows:

(function () {
-VARs and functions are in this scope only
Still maintains access to all globals
}());

Notice the parentheses outside the anonymous function. This is because statements that begin with function in JavaScript are usually considered function declarations. A function expression is created after the outer brackets are added.

Global Import

JavaScript has a feature called a hidden global variable. When a variable name is used, the compiler queries the superior to declare the variable with var. This variable is considered global if it is not found. If used in this way when assigning values, a global scope is created. This means that it is very easy to create a global variable in an anonymous closure. Unfortunately, this can lead to difficult code management because, for programmers, it's not clear if global variables are not declared in one file. Luckily, the anonymous function gives me another option. We can import global variables into our code through the parameters of anonymous functions, which is faster and more neat.

Copy Code code as follows:

(Function ($, YAHOO) {
Now have access to Globals JQuery (as $) and YAHOO into this code
} (JQuery, YAHOO));

Module Export

Sometimes you don't want to use global variables, but you want to declare them. We can easily export them through the return values of anonymous functions. There's so much more to the basics of module mode, and here's a more complicated example.

Copy Code code as follows:

var MODULE = (function () {
var my = {},
privatevariable = 1;

function Privatemethod () {
// ...
}

My.moduleproperty = 1;
My.modulemethod = function () {
// ...
};

return to my;
}());

Here we declare a global module called module, which has two public properties: a method called Module.modulemethod and a variable called Module.moduleproperty. In addition, he maintains a private internal state through the closure of anonymous functions, and of course we can easily import the required global variables using the pattern mentioned previously

Advanced Mode

The previously mentioned content can satisfy a lot of needs, but we can study this pattern more deeply to create some powerful and scalable structures. Let's continue to learn through this module, called module, at 1.1.

Expand

At present, one limitation of the module pattern is that the entire module must be written in a file. Every person who has developed a large code is aware of the importance of separating a file into multiple files. Luckily we have a good way to expand the modules. First we import a module, then add the attribute, and finally export it. The example here is to extend the module using the method described above.

Copy Code code as follows:

var MODULE = (function (my) {
My.anothermethod = function () {
Added method ...
};

return to my;
} (MODULE));

Although not necessary, we use the VAR keyword again for consistency. Then the code executes, and the module adds a public method called Module.anothermethod. The extension file also maintains its proprietary internal state and import.

Pine expansion

The example above requires that we first create a module and then expand on the module, which is not necessary. Asynchronous load scripts are one of the best ways to improve Javascript application performance. Through loose expansion, we create a flexible module that can be loaded into multiple files in any order. The structure of each file is roughly as follows

Copy Code code as follows:

var MODULE = (function (my) {
Add Capabilities ...

return to my;
} (MODULE | | {}));

In this mode, the VAR statement is required. If the imported module does not exist, it will be created. This means that you can load these module files in parallel with a labjs-like tool.

Tight expansion

Although loose expansion has been great, it has also added some limitations to your module. The most important point is that you have no way to safely rewrite the properties of module, and you cannot use the module attribute in other files (but you can use it after initialization) in the initialization process. Tight expansion includes a certain load sequence, but supports rewriting, and here's an example (extending our initial module).

Copy Code code as follows:

var MODULE = (function (my) {
var old_modulemethod = My.modulemethod;

My.modulemethod = function () {
Method Override, has the access to the old through Old_modulemethod ...
};

return to my;
} (MODULE));

Here we have rewritten the Module.modulemethod and kept a reference to the original method as required.

Replication and inheritance

Copy Code code as follows:

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 to my;
} (MODULE));

This pattern may be the least flexible option. While it supports some elegant mergers, the price is at the expense of dexterity. In the code we write, those types are objects or functions whose properties are not copied, only in the form of two references to an object. One changes, the other one also changes. For objects [G5], we can solve them through a recursive cloning operation, but there is no way to function, except for Eval. However, I have included it for completeness.

The private state of a cross file

One big limitation of dividing a module into multiple files is that each file maintains its own private state, and there is no way to get the private state of other files. This can be solved, and the following example of loose expansion can be used to maintain a private state in different files.

Copy Code code as follows:

var MODULE = (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;
};

Permanent access to _private, _seal, and _unseal

return to my;
} (MODULE | | {}));

Each file can set properties for its private variable _private, and other files can be called immediately. When module is loaded, the program calls Module._seal () so that there is no way outside to contact the internal _.private. If the module is to expand again later, one of the properties will change. Before loading a new file, each file can call _.unsea (), and then call _.seal after the code executes.

This pattern comes to mind in my work today, and I have never seen it anywhere else. But I think this is a very useful model that deserves to be written out alone.

Sub-modules

The last advanced mode is actually the simplest, with many examples of creating a child module, just like creating a generic module.

Copy Code code as follows:

Module.sub = (function () {
var my = {};
// ...

return to my;
}());

Although this may be very simple, I decided it was worth writing about. Sub-module has all the quality features of the general module, including expansion and private state.

Summarize

Most advanced modes can be combined to create new, more useful patterns. If I had to come up with a way to design a complex application, I would combine loose expansion, private state, and sub module.

I don't mention performance related things here, but I can say that module mode is good for performance improvement. It can reduce the amount of code, which makes the code more quickly loaded. Loose expansion makes parallel loading possible, which also increases the load speed. The initialization time may be longer than other methods, but it is worthwhile to spend more time. As long as the global variable is imported correctly, there is no problem when running, and the speed may also be raised in the child module because the chain of reference to the variable is shortened.

Finally, this is an example of the dynamic loading of a child module (if it does not exist), I do not consider the internal state for introduction, but even considering it is simple. This pattern allows complex, multi-level code to load in parallel, including the child module and everything else.

Copy Code code as follows:

var UTIL = (function (parent, $) {
var my = Parent.ajax = Parent.ajax | | {};

My.get = function (URL, params, callback) {
OK, so I ' m cheating a bit
Return $.getjson (URL, params, callback);
};

Etc ...

return to parent;
} (UTIL | | {}, jQuery));

I hope that this content is useful, please leave a message below to share your thoughts. Boys, try to write better, more modular JavaScript.

Original link: Ben Cherry translation: Wang Yu

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.