Advanced JavaScript---Modular programming

Source: Internet
Author: User
Tags php programming

As Web sites become "Internet Apps", JavaScript code embedded in Web pages is becoming more and more complex

Web pages are becoming more and more like desktop programs, requiring a collaborative team, schedule management, unit testing, etc... Developers have to use the software engineering approach to manage the business logic of the Web page.

JavaScript modular programming has become an urgent requirement. Ideally, developers only need to implement core business logic, and others can load modules that others have already written.

However, JavaScript is not a modular programming language, it does not support "class", Let's say "module". (The ECMAScript standard Sixth Edition, which is under development, will officially support "Class" and "module", but it still takes a long time to put into practice.) )

The JavaScript community has made a lot of efforts to achieve the "module" effect in the existing operating environment. This paper mainly through the hands-on programming, to achieve a simple version of the require.js to tell how to apply modular programming, as well as the principle of modularization, in order to better understand the require.js and SEAJS and other existing modular management framework. Although this is not a beginner tutorial, you can understand the basic syntax of JavaScript a little bit.

First, the original wording

A module is a set of methods for implementing a specific function.

Simply put the different functions (and the variables that record the state) together, even if it is a module.

function Module1 () {  //...  }function  module2 () {  //... }

The above Functions Module1 () and Mmodule2 () to form a module. When used, call directly on the line.

The disadvantage of this approach is obvious: "Pollute" the global variable, there is no guarantee that the variable name conflicts with other modules, and the module members do not see a direct relationship.

Ii. the wording of the object

In order to solve the above shortcomings, the module can be written as an object, all the module members are placed in this object.

var New  0function  () {  //...  function  () {  //... }});

The above functions M1 () and M2 () are encapsulated in the Module1 object. When used, it is called the property of the object.

MODULE1.M1 ();

However, such a notation exposes all module members, and the internal state can be overridden externally. For example, external code can directly change the value of an internal counter.

Module1._count = 5;

Iii. immediate execution of function notation

Using the Execute functions now (immediately-invoked function Expression,iife), you can achieve the purpose of not exposing private members.

 var  module1 = (function   () { var  _count = 0;  var  m1 = function   () { //  ...     };  var  m2 = function   () { //  ...     };   return   {m1:m1, m2:m2}; })();

Module1 is the basic way of writing JavaScript modules. But the above example only demonstrates the concept of "module", and the more problems we encounter in our work are how to organize these modules. If you have experience in PHP programming, you will think of PHP has a require () function (also some people say this is not a function, because the parentheses can be omitted), when we write module A, if you want to use the previously defined module B, as long as the require (' b.php ') is possible. But there is no such ready-made method in JavaScript. But we know that JavaScript's syntax is very flexible, as long as the use of a certain skill, you can simulate other programming language features, such as our well-known extend () inheritance is a good example. Of course, now this modular require method, there are ready -made libraries can be used, such as require.js, Seajs and so on, but most of them have a huge body, we suddenly difficult to see how it is achieved.

Below I put down my implementation of the simple version of the source code

/** Modular Programming Simple Framework*/;(function() {    //storage of all declared modules    varModules = {}; //storage of parsed modules    varDN = {}    /** * To determine if an array*/    functionIsArray (arr) {returnObject.prototype.toString.call (arr) = = ' [Object Array] '; }    /** Parse the request module * @param {array} ids module ID * @param {function} callback callback*/    functionMakerequire (IDs, callback) {varR =Ids.length, Shim= []; Ids.foreach (function(name,i) {Shim[i]=build (Modules[name])}) if(callback) {callback.apply (NULL, Shim); } Else{shim=NULL; }    }    /** * Parse Dependency * @param {Object} Module Object * @return {array} An array of objects returned by all dependent modules*/    functionParsedeps (module) {varDeps = module[' Deps '], temp= []; Deps.foreach (function(ID, index) {Temp.push (Build (Modules[id))})returntemp; }    /** * Returns the object defined in the module * @param {object} module definition * @return module returned by*/    functionBuild (module) {varExist,exports; Factory= Module[' Factory '], id= module[' id ']; exist=Dn[id]; if(exist) {returnexist; }        if(module[' Deps ']) {depslist=parsedeps (module); Exports=factory.apply (module, depslist); }Else{exports= Factory () | | {}; } Dn[id]=exports; returnexports; }    /** * Import module * @param {ID} ID module ID * @param {function} callback callback function * @return {object}*/    functionrequire (id,callback) {if(IsArray (id)) {returnMakerequire (Id,callback); }        if(!Modules[id]) {            Throw"MODULE" + ID + "Modules do not exist!"; }        if(callback) {varmodule =build (Modules[id]);        Callback (module); }Else{            if(modules[id].factory) {returnModules[id]; }        }    }    /** * Define a module * @param {string} ID module ID * @param {array} deps dependency list * @param {function} Factory module method */    functiondefine (id,deps,factory) {if(Modules[id]) {Throw"MODULE" + ID + "Modules already exist!"; }        //If there is a dependency        if(Arguments.length > 2) {Modules[id]={id:id, deps:deps, factory:factory}}Else{Modules[id]={id:id, factory:deps}}} Window.require=require; Window.define=define;}) ();

The implementation here ignores the issue of the loading and looping dependencies of JavaScript files, because my focus is on the import of modules and on issues of team collaboration development. Personally, there is no need to make an on-demand load, because there is no need to write modules for it. In the development mode, need a function, in the index.html import a JS module, in the product mode, the index.html all JS files in the merge compression, so that only load once, there is no need to load the appearance of the room.

Let me show you how this simple version of the Require.js framework is used.

Actually very simple, as long as know define () is to define a module, require is to call a module on it.

Here are some typical examples:

//define a module aDefine (' a ',function(){      //private variables in module a       varName = ' Module A '; //returns the method implemented by this module    return{A:function(){                        //return the contents of the module as neededconsole.log (name) }})//Define a module BDefine (' B ',function(){       varName = ' Module B '; return{b:function() {Console.log (name)}}) //define a module C, dependent on a, b two modulesDefine (' C ', [' A ', ' B '],function(A, b) {//A, B is the module that module C needs to rely on       //as long as the module ID is given in the form of an array .Console.log (A, b)return{c:function() {Console.log (' Module C ')        }    }})//call A-B two module at the same timeRequire ([' A ', ' B '],function(A, b) {//A is the object returned by module a previously defined       //b Ibid .     //Here you are free to use the methods published in the A/ B module.Console.log (A, B)})//Call C moduleRequire (' C ',function(c) {Console.log (c)})

This allows us to implement a simple modular function. From the above example, isn't it easy to do unit testing? Does the code look very refreshing?

It is not difficult to see the principle of implementation from the code of my bedrooms line, first define modules to collect the module defined, then define a module with define, differentiate by ID, factory return the object provided by this module

The Require, in the case of the request ID, goes to the modules, and if there is no dependency, returns the found object directly, and if there is a dependency, finds the object returned in the dependent module and finally passes them to the callback function. It also considers the case that the ID is an array, that is, it is possible to request multiple modules at the same time, which is just a loop parsing the process. Some books say that define is like an inner ghost, while require is the aggressor. The relationship between them is liyingwaige, the very image of the said. Enrichment is the essence, from this bedrooms line of code to experience the modular implementation principle, is not more than from the thousands of line of require.js slowly mold to ask for more easily?

If you think this article is helpful to you, please click on the recommendation! Thank you, do you want to make progress with me? Then "pay attention" to me!

Advanced JavaScript---Modular programming

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.