Javascript Modular Programming (I): Writing Modules

As the website gradually becomes“ Internet applications "The Javascript code embedded in web pages is becoming larger and more complex.

Web pages are more and more like desktop programs, requiring a team to work together, schedule management, unit testing, etc Developers have to use software engineering methods to manage the business logic of web pages.

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

However, Javascript is not a modular programming language and does not support“ class "(class), let alone" module " ECMAScript Standard The sixth version will officially support "class" and "module", but it will take a long time to put them into practice.)

The Javascript community has made a lot of efforts to achieve the effect of "module" in the existing running environment. This article summarizes the best practices of current "Javascript modular programming" and explains how to put them into practice. Although this is not an initial tutorial, you can understand it as long as you have a little knowledge of the basic syntax of Javascript.

1、 Primitive writing

A module is a set of methods to achieve a specific function.

As long as different functions (and variables that record state) are simply put together, it is a module.

  function m1(){
    //...
  }

  function m2(){
    //...
  }

The above functions m1() and m2() form a module. When using, just call directly.

The disadvantage of this approach is obvious: it "pollutes" the global variables, cannot guarantee that the variable names will not conflict with other modules, and there is no direct relationship between module members.

2、 Object Writing

To solve the above shortcomings, you can write a module as an object, and all module members are placed in this object.

  var module1 = new Object({

    _count : 0,

    m1 : function (){
      //...
    },

    m2 : function (){
      //...
    }

  });

The above functions m1() and m2() are encapsulated in the module1 object. When using, it is to call the properties of this object.

  module1.m1();

However, such writing will expose all module members, and the internal state can be overwritten externally. For example, external code can directly change the value of internal counter.

  module1._count = 5;

3、 Execute function writing immediately

Using“ Execute function now "(Immediate Invoked Function Expression, IIFE) can achieve the goal of not exposing private members.

  var module1 = (function(){

    var _count = 0;

    var m1 = function(){
      //...
    };

    var m2 = function(){
      //...
    };

    return {
      m1 : m1,
      m2 : m2
    };

  })();

Using the above writing method, the external code cannot read the internal _count variable.

  console.info(module1._count); // undefined

Module1 is the basic way to write Javascript modules. Next, we will process this writing method.

4、 Zoom in mode

If a module is large and must be divided into several parts, or one module needs to inherit another module, then it is necessary to adopt "amplification mode".

  var module1 = (function (mod){

    mod.m3 = function () {
      //...
    };

    return mod;

  })(module1);

The above code adds a new method m3() for module1 module, and then returns the new module1 module.

5、 Loose amplification

In the browser environment, each part of the module is usually obtained from the Internet, and sometimes it is impossible to know which part will be loaded first. If the writing method in the previous section is used, the first execution part may load an object that does not exist empty. In this case, the "Wide Enlargement Mode" should be used.

  var module1 = ( function (mod){

    //...

    return mod;

  })(window.module1 || {});

Compared with "zoom in mode", "wide zoom in mode" means that the parameters of "execute function immediately" can be empty objects.

6、 Enter global variables

Independence is an important feature of a module. It is better not to directly interact with other parts of the program inside the module.

In order to call global variables within a module, other variables must be explicitly entered into the module.

  var module1 = (function ($, YAHOO) {

    //...

  })(jQuery, YAHOO);

The module1 module above needs to use the jQuery library and YUI library, so these two libraries (actually two modules) are input as parameters into module1. This not only ensures the independence of modules, but also makes the dependency between modules obvious. For more discussion, see Ben Cherry's famous article 《JavaScript Module Pattern: In-Depth》

The second part of this series will discuss how to organize different modules and manage dependencies between modules in the browser environment.

(End)

Message (89)

It's very simple. It's easy to understand. Thank you.

It is recommended to write Common JavaScript and Yubo's SeaJS: http://seajs.org/

3、 Are the four, five and six brackets wrong?

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

The example in the above link is as follows:
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());

The usage of "()" is different from that of the code given by Yifeng. What is the difference between the two writing methods?

http://nuysoft.iteye.com/blog/1177451

Open the jQuery source code, and first you will see the code structure:
(function( window, undefined ) {
// jquery code
})(window);
1. This is a self calling anonymous function. What? In the first parenthesis, create an anonymous function; The second bracket, execute immediately
2. Why create such a "self calling anonymous function"?
By defining an anonymous function, a "private" namespace is created. The variables and methods of this namespace will not destroy the global namespace. This is very useful, and it is also a function that the JS framework must support. jQuery is used in thousands of JavaScript programs. You must ensure that the variables created by jQuery do not conflict with the variables used by the imported program.
3. Anonymous functions are syntactically called function literals. JavaScript syntax requires parentheses around anonymous functions. In fact, there are two ways to write self calling anonymous functions:
(function() {
console.info( this );
console.info( arguments );
}( window ) );
------------------------------------
(function() {
console.info( this );
console.info( arguments );
})( window );

Want to know about the AMD module

Big love brother Ruan's js article! Share it decisively!

Clear thinking, easy to understand.

Well, I think the current javascript is very good. You can also implement modules and classes. Just like assembly can also produce various styles.

Brother Ruan, is javascript suitable for writing long running programs?
I wrote a long running javascript program before, but the user responded that,
After running the program for several hours, the system will run out of memory.

I checked the task manager and found that running javascript programs in the browser for a long time would lead to
Memory leak. I wonder if Brother Ruan has ever encountered such a problem.
According to the results of my online search, this may be a problem with the browser.
I haven't found the reason. I don't know what's going on now.

Also, when you write large javascript programs, will memory leaks occur?

Concise, clear and thorough

Well, it's been a long time

Hello, I'm a novice. Why does the third step use the immediate execution function writing method to protect private variables from being changed

In amplification mode, you can extend the incoming module to achieve "inheritance". What if you want to extend the private method of the module?

Easy to understand, not bad

This is good. I collected it

If you use coffee script, don't you have to worry about it?

 Quoted from Zhang Xu:

If you use coffee script, don't you have to worry about it?

same

 To quote nakseuksa's statement:

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

The example in the above link is as follows:
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());

The usage of "()" is different from that of the code given by Yifeng. What is the difference between the two writing methods?

These two writing methods are both OK, and there are no grammatical errors. It seems that foreign countries like (function() {}()); Domestic people prefer (function () {}) ();

 To quote nakseuksa's statement:

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

The example in the above link is as follows:
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());

The usage of "()" is different from that of the code given by Yifeng. What is the difference between the two writing methods?


(function() {} ()) uses mandatory operators to perform function call operations, and (function() {}) () uses function call operators to operate function references. The two functions are the same, but the operation process is different.

Good article, jack up! And the page code makes people feel very comfortable. The more you look, the more you want to look down... Can't put it down

It's so handsome~awesome

Such an article is really a masterpiece of technical articles!

Dry goods, but melt at the entrance!

The fourth point is not clear. Can someone explain it?

 Quote Chen Sanshi's speech:

Hello, I'm a novice. Why does the third step use the immediate execution function writing method to protect private variables from being changed

The citation execution function only returns functions m1, m2

Thank you for sharing.

Easy to understand good writing!

Thank you very much. The articles written are easy to understand and understand!

Part 4:
var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);
It is written as:
(function (mod){
    mod.m3 = function () {
      //...
    };
  })(module1);
Or:
module1.m3 = function () {
      //...
    };
The m3 method is also extended for module1. What's the difference?

Why do I always think your head looks like a manager I met during my interview in Wudaokou, but I searched your information online and said you taught in Shanghai

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
var module1 = function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  }();
What is the difference between the two writing methods? The second is what I saw in the book Advanced Programming in javascript. thank you!

Brother Ruan Yifeng's article is easy to understand. Thank you very much for answering many questions for me!

 To quote nakseuksa's statement:

http://www.adequatelygood.com/2010/3/JavaScript-Module-Pattern-In-Depth

The example in the above link is as follows:
(function () {
// ... all vars and functions are in this scope only
// still maintains access to all globals
}());

The usage of "()" is different from that of the code given by Yifeng. What is the difference between the two writing methods?


No difference

Who will answer the questions of Li Chao and csu

I remember how to modify and read private variables
var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
var getCount = function(){
return this._ count;
};
var setCount = function(newCount){
//Of course, you don't need to construct this method if you don't need to modify it
this._ count = newCount;
};
    return {
      m1 : m1,
      m2 : m2,
getCount : getCount,
setCount : setCount
    };
  })();

Very good. I just don't understand this aspect. I hope Harmony will come soon, so I don't have to hack like this.

 Quote Hedgehog's statement:

I remember how to modify and read private variables
var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
var getCount = function(){
return this._ count;
};
var setCount = function(newCount){
//Of course, you don't need to construct this method if you don't need to modify it
this._ count = newCount;
};
    return {
      m1 : m1,
      m2 : m2,
getCount : getCount,
setCount : setCount
    };
  })();

this._ count; It should be changed to _count;


Li Chao:

1. To cascade
For example, module1. m3(). m2()
2. It's the question of private variables that has been mentioned in this article

 Quote the statement of csu:

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
var module1 = function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  }();
What is the difference between the two writing methods? The second is what I saw in the book Advanced Programming in javascript. thank you!

There is no difference between the two writing methods
But that's not right:
(function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  }();
The second writing method here will cause errors in parsing the syntax tree.

When you see the realization of zooming in, your eyes will brighten!

var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);

Isn't this an error??? Did you write something wrong????

Like a good article.

I feel your blog is a bit crude, so I suggest adding one back to the top

Great teacher~learned

Good writing, easy to understand, learned~~~~·

fabulous! The context is very clear.

The original module is essentially a variable returned by "execute function immediately". In addition, similar to Python, the scope of JavaScript is also a dictionary in essence.

Just solve my current problem; Combined with the project in mind; I study!

It has been 12 years. I only blame myself for seeing it too late!

There is something wrong with the code of 4.
var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);
Your module1 is referenced when it is defined. Unless module1 is defined as an object before, it is repeated here.

I have been paying attention to Daniel's articles all the time. I can only say that it is really a good introduction for learners to explain in simple terms.

Good writing, easy to understand. Like one!

What's the meaning of the last one? I don't quite understand

It is simple and clear, much better than the Javascript Design Pattern I bought. That book is translated from abroad, which is nonsense....

var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);
Known module module1, alias mod in anonymous function. After adding m3 objects, return mod. At this time, module1 also has a m3 object.

However, module1 may not exist, which will report an error. We will improve.
var module1 = ( function (mod){
    //...
    return mod;
  })(window.module1 || {});

At this time, if there is no global module1, just pass in the {} empty object. Remember that you cannot replace window.module1 with module1.

 Quote from Yuyuyu's statement:

var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);

Isn't this an error??? Did you write something wrong????

The whole is the combination of variable declaration and assignment expression. According to the priority, the module1 variable will be declared first, then the value of the expression on the right of "=" will be calculated, and finally the calculated value will be assigned to the declared variable module1. However, when calculating the expression on the right, the anonymous function will execute immediately, and the priority declared variable module1 will be passed in when executing immediately. However, module1 is just an empty variable without type. After it is introduced into the anonymous function as an actual parameter, it cannot set properties because the formal parameter mod in the anonymous function is not an object, and an error will be reported. Just modify it: var module1 = {} module1 = (function (mod){ mod.m3 = function () { //... }; return mod; })(module1);

Mr. Ruan spoke very well and meticulously. With the addition of many commentators, the effect was really good. Thank you.

 Quote the speech of Feihong Shadow:

However, module1 may not exist, which will report an error. We will improve.
var module1 = ( function (mod){
    //...
    return mod;
  })(window.module1 || {});

At this time, if there is no global module1, just pass in the {} empty object. Remember that you cannot replace window.module1 with module1.


Can you explain in detail why you must use window.module1? Can't I use module1 directly?

I also want to ask why you can't use module1? You must use window.module1?
Later, I tested it and found that all the codes were OK as follows:
var module1 = (function(mod){
mod.said = function(){
alert("hello liuyufang");
}
return mod;
})(module1||{});

module1.said();

 Quote the statement of csu:

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
var module1 = function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  }();
What is the difference between the two writing methods? The second is what I saw in the book Advanced Programming in javascript. thank you!

I wonder if you are still looking here, teacher? Can it really work in the second writing method? Because in my opinion, there are only two ways to write anonymous function self execution, one is (function() {} ()), the other is (function() {}) (), and the second way should not be to think that it is over after reaching the last one?

The third point mentioned by the owner is that it is wrong that the private variable cannot be accessed by executing the function immediately. The essence of the inaccessible variable is that the variable does not belong to the object. For example:


var createObj=function(){
var count=3;
this.username="lidaxia";
this.getUserName=function(){
return this.username;
};
return this;
};
var person=createObj();
alert(person.count);

You cannot access count, but you can access username. Your immediate execution function does not assign variables to objects, just like mine

 Quote from Liu Yufang:

I wonder if you are still looking here, teacher? Can it really work in the second writing method? Because in my opinion, there are only two ways to write anonymous function self execution, one is (function() {} ()), the other is (function() {}) (), and the second way should not be to think that it is over after reaching the last one?

Just tried, (function() {} ()) and (function() {}) () can be executed, var x=function() {} () can also be executed, but function() {} (); This is an error. The function has no name. While function xx () {} (); This one with a name does not report an error, but does not execute until the last one

 Quote from Liu Yufang:

I wonder if you are still looking here, teacher? Can it really work in the second writing method? Because in my opinion, there are only two ways to write anonymous function self execution, one is (function() {} ()), the other is (function() {}) (), and the second way should not be to think that it is over after reaching the last one?

The second method is available if variables are added in front of it. If only function() {...}() is written; An error will be reported. Is it considered that the variable added in front is not an anonymous variable???

var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
    return {
      m1 : m1,
      m2 : m2
    };
  })();
The function expression can be called immediately if it is directly enclosed in parentheses at the end. Why should it be enclosed in parentheses

How does magnification mode realize amplification and inheritance?

@Chen Sanshi is also a novice. In my opinion, when the function returns, the return value replaces the function, so there is no external reading except the return value.

I think the building owner made a mistake in writing the function immediately. How can an object get a variable in the form of a key value? Even if there is no return, it is undefined

@Great Xia Li:

If you write person like this, it means that the global object window of the current context | | global, username and getUserName become properties of the global object

Immediate Invoked Function Expression (IIFE) can achieve the goal of not exposing private members.

Closures:
Closures are functions that refer to independent (free) variables (variables that are used locally, but defined in an enclosing scope). In other words, these functions 'remember' the environment in which they were created.

AMD, CMD, CommonJS and UMD

The AMD module is developed on the principle of browser first, and the module is loaded asynchronously;
CommonJS module is developed according to the principle of server first, and synchronous loading is selected;
UMD is the combination of AMD and CommonJS;

After reading, I got a start in understanding the JS module. thank you

 Quote Hedgehog's statement:

I remember how to modify and read private variables
var module1 = (function(){
    var _count = 0;
    var m1 = function(){
      //...
    };
    var m2 = function(){
      //...
    };
var getCount = function(){
return this._ count;
};
var setCount = function(newCount){
//Of course, you don't need to construct this method if you don't need to modify it
this._ count = newCount;
};
    return {
      m1 : m1,
      m2 : m2,
getCount : getCount,
setCount : setCount
    };
  })();

P. S. Where setCount is defined, it should be return _count; The children's shoes have just been pointed out.

But what if the user calls module1. setCount()? Isn't the _count variable still unsafe?

The sixth global mode is not very clear.
Assuming that jquery is referenced in the page, you don't need to pass jquery into the parameter passing of the immediate function. You can also call $internally.

Don't you find that there is a problem in executing the function immediately? None of m1's () were added
//Execute function now
var module = (function(){
var _count = 0;
var m1 = function() {
console.log("m1");
};
var m2 = function() {
console.log("m2");
};
return {
m1 : m1(),
m2 : m2()
};
})();

 To quote MinYong's statement:

Don't you find that there is a problem in executing the function immediately? None of m1's () were added
//Execute function now
var module = (function(){
var _count = 0;
var m1 = function() {
console.log("m1");
};
var m2 = function() {
console.log("m2");
};
return {
m1 : m1(),
m2 : m2()
};
})();

It is correct not to add (), because the function is copied to the m1 variable, instead of letting it run, it is run using module. m1() during instantiation

Teachers are good at giving lectures. They explain from simple to deep, from the outside to the inside, and thank the blogger for his contribution.

 Quote from Yuyuyu's statement:

var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);

Isn't this an error??? Did you write something wrong????

I also encountered the same problem. Here I will tell you the reason for the error. Because "amplification mode" can be regarded as expanding the original function to achieve the "amplification purpose", it is necessary to have a module1 function before referencing this code. See if you have directly executed this code

Please follow and star. My github homepage: sunshine940326.github.io

That's very good, but it's still difficult for beginners to use it in their own projects! For example, my current project is a live broadcast on a page. There are many functions on this page, such as customized progress bars, windows that change size according to different locations and user operations, pull up and refresh, send comments, etc. My writing method is to directly write one function after another in a js file, and then import, However, there are many global variables in it, and more functions will be added in the future, so I just want to find a way to manage these functions. This article is very good, but I don't know how to use it!

 To quote nakseuksa's statement:

3、 Are the four, five and six brackets wrong?

 Quote Chen Sanshi's speech:

Hello, I'm a novice. Why does the third step use the immediate execution function writing method to protect private variables from being changed

This is related to the scope of variables. They are local variables, so they cannot be obtained externally. Since they cannot be obtained, how about modification? That is to protect private variables from modification.

var module = (function(){
var m1 = function(){};
var m2 = function(){};
return{m1:m1,m2:m2}
})(windows.module||{});
I want to write new module() externally;
How to write the constructor in the code

What has been used in the projects I have done since I started to contact with modular programming last year is still confused. There are too many theories on the Internet. The more I read the more I don't understand the whole article, the more I read the introduction written by the big guy today, combined with what was used in the projects before, it becomes clear at a glance. Thank you for your help.

Ruan Shen wrote an article five years ago, but I was typing DOTA five years ago. Now I'm really sad

It's really much better than other websites. The context is clear. Thanks for sharing!

All good words are simply said once. After reading Brother Ruan's blog, I feel that it is simple but not simple. It is estimated that it is the work after reading countless articles. In a word, it is also connected with ancient and modern times.

Teacher Ruan's blog is really good. Although it seems very simple, there are still many essences inside. You can learn a lot from it. Let me summarize my understanding
1. Five common ways to write closures
(function(){}())
(function(){})()
These two writing methods ensure that they do not start with function directly, so the following writing methods are the same
var a = function(){}()
var a = (function(){}())
Var a=(function() {}) ()//It is used to
Other situations will not be discussed

2. Some students are asking what is the difference between the third amplification mode and the following one,
  var module1 = (function (mod){
    mod.m3 = function () {
      //...
    };
    return mod;
  })(module1);

mod.m3 = function () {};
In fact, it doesn't make any difference. The teacher's writing method ensures that if you need to define private variables at the same time, you can use the teacher's method. The following method doesn't need the teacher to point out that everyone understands it.

3. Some students complained about the amplification mode of Example 4. Let me explain it here
The teacher said that if you need to inherit, you can use the amplification mode. Then the module 1 already exists. If you are not sure that the module already exists, you can use the fifth wide amplification mode. The teacher analyzed the situation step by step,

4. Some students are asking why they must use window.module1. I think it sounds strange, and then tested it. No problem. Then they began to guess what would lead to the use of window.module1. Suppose this happens
var module1 = (function(){
count = 1
var m1 = function(){

}
return { m1:m1}
})()
(function(){
var module1 = ( function (mod){
    //...
    return mod;
  })(module1 || {});
})()
Then this situation is wrong. Because in the following closure, module1 is initialized to undefined. At this time (module1 | | {} results in {}), the first module has no role. Therefore, window.module1 should be used to ensure that module1 is a global variable
(function(){
var module1 = ( function (mod){
    //...
    return mod;
  })(window.module1 || {});
})()
If my speech is wrong, I hope you can point it out to me

Use closures to avoid global variable pollution and reduce content disclosure

I'm a little unclear now, when to use the class pattern and when to use the modular pattern?

In simple terms, a white like me can understand it slowly. Thanks for sharing!

I want to express my opinion

« - Required

« - Required, not open

« - I trust you and will not fill in the advertising link