JS namespace Mode parsing

Source: Internet
Author: User
Tags object object

Introduction

On SF, you see a question like this:

Title, there are several global functions that need to be written because of a forced reason. But not like this:

functionfunction function () {}

What is the best way to say the question?

Answer:

If you use JQuery, you can write like this.

$.extend (window, {    function() {},    function() {},     function () {}});

If you don't use jQuery, you can directly implement a similar extend:

()    = {var defining = {        function() {        },function  () {},        function() {}    };     = =        {= Defining[key];    });}) ();

In JavaScript, namespaces can help prevent conflicts with other objects or variables under the global namespace. namespaces also help organize your code, with greater maintainability and readability. The purpose of this article is to explore several common namespace patterns in JavaScript, providing us with a way of thinking.

The implementation of a generic namespace is rooted in window. When requesting a A.B.C namespace from window, first look in the window to see if a member exists, and if not, create a new empty associative array named a under window. If a is already present, continue to see if B exists in WINDOW.A, and so on. The following are the implementation methods in Atlas and Yui respectively.

How to implement the Atlas namespace :

Function.registernamespace =function(namespacepath) {//take window as root    varRootobject =window; //splitting the namespace path into arrays    varNamespaceparts =namespacepath.split ('. '));  for(varI =0;i <namespaceparts.length;i++) {        varCurrentpart =Namespaceparts[i]; //if the current namespace does not exist, a new object object is created, which is equivalent to an associative array.         if(!Rootobject[currentpart]) {Rootobject[currentpart]=NewObject (); } rootobject=Rootobject[currentpart]; }}

Another way to achieve this:

namespace =function(){    varArgus =arguments;  for(vari = 0; i < argus.length; i++){        varOBJS = Argus[i].split (".")); varobj =window;  for(varj = 0; J < Objs.length; J + +) {Obj[objs[j]]= Obj[objs[j]] | | {}; Obj=Obj[objs[j]]; }    }    returnobj;}; Namespace ("Tools.base");

we often use the JS object literal way to implement the JS namespace :

var school = {    addclass:function(classnum) {        console.log (classnum);    },    addstudent: function (stuid) {        console.log (stuid);    }} School.addclass ("2");

Any variables and functions declared in the global scope are properties of the Window object, and when there are conflicting names, there are some problems that are not controllable. Global variables can cause the following problems:

    • Naming conflicts
    • The fragility of the code
    • Difficult to test

A reasonable use of namespaces in programming development avoids collisions of the same variables or object names. Also, namespaces help organize your code, which is more maintainable and readable. Although there is no native namespace support available in JavaScript, we can use other methods (objects and closures) to achieve similar effects. Here are some common namespace patterns:

1. Single global variable

A popular namespace pattern in JavaScript is to select a global variable as the primary reference object. Because each possible global variable becomes a property of a unique global variable and no more global variables are created, conflicts with other claims are avoided.

The single global variable pattern is already in use in a number of JavaScript class libraries, such as:

    • Yui defines the only Yui global object
    • jquery defines $ and jquery,$ used by other class libraries when using jquery
    • Dojo defines a dojo global variable
    • The Closure class library defines a Goog global object
    • The underscore class library defines a _ global object

Examples are as follows:

var myapplication = (function() {    var count = 1;      function funcur () {        console.log (count);     };      return {        funcur:funcur     }}); Myapplication.funcur ();

While a single global variable pattern is appropriate for some situations, the biggest challenge is to ensure that a single global variable is unique in the page and that no naming conflicts occur

2. Namespace prefixes

namespace prefix pattern It is very clear that you choose a unique namespace, and then declare variables, methods, and objects behind it. Examples are as follows:

var = Myapplication_propertya = {}; var = Myapplication_propertya = {}; function Myapplication_mymethod () {    //  * *}

In a way, it does reduce the probability of a naming conflict, but it does not reduce the number of global variables. When an application is scaled up, it produces many global variables. Within the global namespace, this pattern is strongly dependent on the prefix that no one else is using, and it is sometimes difficult to determine whether someone has used a particular prefix, and it is important to pay special attention when using this pattern.

3. Object literal notation

The object literal pattern can be thought of as an object that contains a set of key-value pairs, with each pair of keys and values separated by colons, or a new namespace for the code. Examples are as follows:

var myapplication = {    //  can be easily defined for the object literal    getInfo: function () {        //  *    },        //  can further support the object namespace     models:{},    views:{        pages:{}}    ,    collections:{}};

As with adding properties to an object, we can also add properties directly to the namespace. The object literal method does not pollute the global namespace and logically assists in organizing code and parameters. Moreover, the readability and maintainability of this method is very strong, of course, we should use the same name as the existence of variables to test, so as to avoid conflicts. Here are some common detection methods:

var myapplication = MyApplication | |  {}; if (! MyApplication) {    MyApplication  =| | (Window.myapplication | |  {}); // for jquery var function () {}; var myapplication = MyApplication = = = undefined? {}: MyApplication;

The object literal provides us with an elegant key/value syntax that allows us to organize the code very easily, encapsulating different logic or functionality, and is extremely readable, maintainable, and extensible.

4. Nesting namespaces

The nested namespace pattern can be said to be an upgraded version of the object literal pattern, which is also an effective way to avoid conflicts, because even if a namespace exists, it is unlikely to have the same nested object. Examples are as follows:

var myapplication = MyApplication | |  {};   // defining nested subwebs myapplication.routers = Myapplication.routers | |  = MyApplication.routers.test | | {};

Of course, we can also choose to declare a new nested namespace or property as an indexed property, such as:

myapplication[' routers ' = myapplication[' routers '] | | {};

Using nested namespace patterns makes code easy to read and organized, and relatively secure and less prone to conflict. The downside is that if our namespaces are nested too much, we increase the query effort of our browsers, and we can reduce the query time by locally caching sub-objects that we want to access multiple times.

5. Function expressions that are called immediately

The immediate call function (Iife) is actually an anonymous function that is called immediately after it is defined. In JavaScript, function calls provide a convenient way to implement private variables and methods because variables and functions are explicitly defined in such a context that can only be accessed internally. Iife is a common method for encapsulating application logic to protect it from the global namespace, which can also play a special role in namespaces. Examples are as follows:

;(function(namespace, undefined) {//Private Properties    varfoo = "Foo"; Bar= "Bar"; //public methods and propertiesNamespace.foobar = "Foobar"; Namespace.sayhello=function() {Say ("Hello world!");    }; //Private Methods    functionSay (str) {Console.log ("You said:" +str); };}) (Window.namespace= Window.namespace | | {});
Console.log (Namespace.foobar); //Foobar

Extensibility is the key to any scalable namespace pattern, which can be easily achieved with iife, and we can use Iife again to add more functionality to the namespace.

6. Namespace Injection

Namespace injection is another variant of iife, which "injects" methods and properties into a specific namespace from within the function wrapper, using this as the namespace proxy. The advantage of this pattern is that functional behavior can be applied to multiple objects or namespaces. Examples are as follows:

varMyApplication = MyApplication | |{};myapplication.utils= {};;(function () {    varValue = 5;  This. GetValue =function () {        returnvalue; }    //to define a new sub-namespace     This. Tools = {};}). Apply (myapplication.utils);(function () {     This. Diagnose =function () {        return"Diagnose"; }}). apply (myApplication.utils.tools);//The same approach extends functionality on ordinary iife, simply passing the context as a parameter and modifying it, rather than just using this

There is also a way to use the API to achieve a natural separation of context and parameters, which feels more like the creator of a module, but as a module, it also provides an encapsulation solution. Examples are as follows:

varNS = NS | |{}, ns1= NS1 | | {};//module, namespace creatorvarCreator =function(val) {varval = val | | 0;  This. Next =function () {        returnVal + + ;    };  This. reset =function() {Val= 0; }}creator.call (NS);//Ns.next, Ns.reset already exists at this timeCreator.call (ns1,5000);//ns1 contains the same method, but the value is overridden to be 5000.Console.log (Ns.next ());//0Console.log (Ns1.next ());// the

Namespace injection is used to specify a similar feature base set for multiple modules or namespaces, but it is best to use it when declaring a private variable or method, and other times the use of nested namespaces is sufficient.

7. Automatic nesting of namespaces

Nested namespace patterns provide an organized hierarchical hierarchy of code units, but each time you create a hierarchy, we also have to ensure that it has a corresponding parent level. When the number of levels is large, it can bring us a lot of trouble, we can not quickly and easily create the level you want to create. So how do we solve this problem? Stoyan Stefanov proposes to create a method that receives a string parameter as a nested, parses it, and automatically populates the base namespace with the desired object. Here is an implementation of this pattern:

functionExtend (ns, nsstr) {varParts = Nsstr.split (".")), Parent=NS, PL; PL=parts.length;  for(vari = 0; i < pl; i++) {        //property if it does not exist, create it        if(typeofParent[parts[i]] = = = "undefined") {Parent[prats[i]]= {}; } Parent=Parent[parts[i]]; }    returnparent;}//usagevarMyApplication = MyApplication | | {};varMoD = Extend (MyApplication, "module.module2");

Previously we had to explicitly declare various nested objects for their namespaces, and now they are implemented in a more concise and elegant way.

Reference Address: http://www.cnblogs.com/syfwhu/p/4885628.html

JS namespace Mode parsing

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.