JS Library notation

Source: Internet
Author: User
Tags define function

Objective:

Now the JavaScript library is very many, its writing all sorts, summarizes several we often see, as own knowledge accumulation. The current version of JavaScript does not provide a native, language-level modular organizational model, but rather a modular approach for developers. As a result, there are many ways to implement JavaScript modularity,

In AMD, for example, the specification uses the Define function to define a module.

define (Factory () {    // Modular });

Module mode:

Module mode uses a feature of JavaScript, the closure (Closures). Some of today's popular JS libraries often see the following forms of code:

;(function  (parameter) {  //  module code  //  return something;}) (parameters);

The above code defines an anonymous function and immediately calls itself.

Some developers also precede the function expression with an exclamation point (!) or a semicolon (;), instead of enclosing it in parentheses.

! function (parameter) {  //  code  //  return something} (parameter);

Others like to enclose the whole iife in parentheses, which becomes the following form:

(function  (parameter) {  //  code  //  return something} (parameters));
Parameter input:

JavaScript has an attribute called an implicit global variable (implied globals), and when a variable name is used, the JavaScript interpreter iterates through the scope chain to find the declaration of the variable, assuming that the variable is a global variable if it is not found. This feature allows us to refer to global variables, such as jQuery or window, anywhere in the closure. However, this is a bad way.

Considering the module's independence and encapsulation, references to other objects should be introduced through parameters. If other global objects are needed within the module, they should be explicitly referenced as parameters rather than directly referencing the names of those objects within the module. In the case of jquery, it is possible to make an error if the object is referenced directly within the module without entering the jquery object in the parameter. The right way should be roughly like this:

;(function  ($, W) {  //  $ is jQuery  //  w is window  // local variables and codes  // return }) (JQuery, window);
Module output (Modules export)

Sometimes we don't just want to use global variables, we also declare and output the objects in the module, which can be achieved by the return statement of the anonymous function, which also forms a complete module pattern.

 var  klm= (function   () { var  myklm = {}, modeval  =     1 function   Privatemethod () { //  ...      Myklm.moduleproperty  = 1 = function   () {//  ...      };  return   MYKLM;} ());

This code declares a variable MODULE with two accessible properties: Moduleproperty and Modulemethod, and the rest of the code is encapsulated in a closed package that remains private. Referring to the previously mentioned parameter inputs, we can also refer to other global variables by parameters.

To output a Simple object:

It is common to use object direct amounts to express JavaScript objects. For example: var x = {p1:1, p2: "2", f:function () {/* ... */}}

varModule1 = (function () {  varprivate_variable = 1; functionPrivate_method () {/*...*/ }   varmy ={property1:1, Property2:private_variable, Method1:private_method, Method2:function () {        // ...    }  }; returnmy;} ());
Output function:

Sometimes what we want to return is not an object, but a function. There are two requirements that require us to return a function, in which case we need it to be a function, such as JQuery, which is a function rather than a simple object, and the other is that we need a "class" instead of a direct amount, and then we can use "new" to instantiate it. The current version of JavaScript does not have a special "class" definition, but it can be expressed by function.

 var  klm= (function   () { //  Private members and code ...  return  function   this . Name = name;  function  () {/*   ...  */  var  com = new  KLM ("Quine sensitive"  

As mentioned earlier, one form is the direct amount of the Output object (object Literal Notation), and revealing Module pattern is actually this form, just a few limitations. This pattern requires defining variables and functions within the private scope, and then returning an anonymous object in which to specify the members to expose.

var klm= ( function () {  //  private variable and function  var x = 1;   function F1 () {}   function F2 () {}    return {    public_method1:f1,    public_method2:f2  };} ());
Extension: Tight coupling extension:

Sometimes we ask to invoke methods that have been previously defined in the extension, which can also be used to overwrite existing methods. In this case, the order of definition of the module is required.

var klm = (function  (my) {  var old_modulemethod = my.modulemethod;    function () {    //  method overloads    //  can call previous methods via Old_modulemethod ...   };   return my;} (KLM));
Cloning and Inheritance:
varModule_two = (function(old) {varmy ={}, key;  for(KeyinchOld ) {        if(Old.hasownproperty (key)) {My[key]=Old[key]; }    }     varSuper_modulemethod =Old.modulemethod; My.modulemethod=function () {        //override method on the clone, access to super through Super_modulemethod    }; returnmy;} (MODULE));

The above code is streamlined: you can use Object.create ()

var Module_two = (function  (old) {  var my = object.create (old);    var super_modulemethod = old.modulemethod;   function () {    //  override method ...   };    return my;} (MODULE));
Adaptation to other module specifications or JS libraries: module Environment Detection:

Today, CommonJS Modules and AMD have a wide range of applications, and if it is determined that AMD's define is available, we can of course use define to write modular code. However, we cannot assume that our code will necessarily run in an AMD environment, is there any way to get our code?

In fact, we just need to add the CommonJS Modules and AMD in a certain place and "register" themselves based on the results of the probe, which are still useful. AMD defines the Define function, and we can use TypeOf to detect whether the function is defined. To be more rigorous, you can continue to determine whether DEFINE.AMD has a definition. In addition, SEAJS also uses the Define function, but not the same as AMD's define. For CommonJS, you can check whether exports or module.exports are defined.

 var  KLM = (function   () { var  my = {};    //  code ...  if  (typeof  define = = ' function '  Span style= "color: #0000ff;"  >function  () {return   my;});  else  if  ( typeof  module! = ' undefined ' && = my;  return   my;} ());
Some other JS library practices

How jquery is detected

if(typeofmodule = = = "Object" && module &&typeofModule.exports = = = "Object") {Module.exports=JQuery;} Else {    if(typeofdefine = = = "function" &&define.amd) {define ("jquery", [],function() {returnJQuery;}    ); }} if(typeofwindow = = = "Object" &&typeofWindow.document = = = "Object") {Window.jquery= window.$ =jQuery;}

Next look at the practice of multiple anonymous functions:

(function(root, factory) {if(typeofExports = = = "Object" &&exports) {Factory (exports);//CommonJS}Else {    varMustache = {};    Factory (mustache); if(typeofdefine = = = "function" &&define.amd) {define (mustache);//AMD}Else{root. Mustache= Mustache;//<script>    }  }}( This,function(mustache) {//The main code of the module is put here.});

This code is not the same as the one described earlier, it uses two anonymous functions. The latter function can be thought of as the factory function of the module code, which is the main part of the module. The previous function detects the running environment and invokes the factory function of the module based on the result of the detection. In addition, as a common library, it does not use the Window object, but instead uses this, because in a simple function call, this is actually a global object.

And look at DoT's approach.

(function() {    "Use Strict"; varDoT ={version:' 1.0.0 ', templatesettings: {/*...*/}, template:undefined,//FN, compile templatecompile:undefined//FN, for Express    }; if(typeofModule!== ' undefined ' &&module.exports) {module.exports=DoT; } Else if(typeofdefine = = = ' function ' &&define.amd) {define (function(){returnDoT;}); } Else {        (function(){return  This|| (0,eval) (' this '); } ()). DoT =DoT; }    // ...}());

This code (0, eval) (' This ') is a little trick, the expression used to get the global object, ' this ' is actually passed to the eval parameter, but since Eval is obtained indirectly through the expression (0, eval), Eval will be in the global This is found in the object scope, resulting in a global object. If the code is running in a browser, then the Window object is actually obtained.

The future of JavaScript in a modular format

ES 6, which is still in development, defines the language level of the module. Let's take a look at an example, and the following snippet is excerpted from "a couple of new things in Es6:javascript."

module Car {   //  internal variable  var licenseplateno = ' 556-343 ';    // exposed to external variables and functions  function Drive (speed, direction) {     Console.log (' details: ', speed, direction);   }   Export Module engine{     function  check () {}   }   var miles = 5000 ;    var color = ' silver ';};

In the future when I write the JS package above is my reference material, continue the passion of the forward ...

JS Library notation

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.