The basic methods of creating objects in JavaScript are literal declarations (object Literal) and constructors, but JavaScript does not have special syntax to represent concepts in object-oriented programming such as namespaces, modules, packages, private properties, static properties, and so on. To enable JavaScript to implement advanced semantics in object-oriented programs, people have invented namespace patterns, dependency declaration patterns, module patterns, and sandbox patterns.
1. Namespace ModeThe namespace pattern solves two problems in JavaScript, one is the problem of global variable pollution, and the other is the possible name conflict problem. Although JavaScript does not specifically support namespaces, namespace patterns are not difficult to implement in JavaScript. In order not to use the global variable too much, you can organize all the global variables used in the program into one (preferably a program with only one) global object. Next, to access the required variables, you can use this object to get a reference:
Before:5 globals//warning:antipattern//constructorsfunction Parent () {}function child () {}//a variablevar Some_var = 1;//some Objectsvar module1 = {};module1.data = {a:1, B:2};var module2 = {};
The above code has 5 global variables, a global object, and a global simple type variable. This creates a global object named MyApp, and then organizes the above 5 global variables into the MyApp:
After:1 global//Global Objectvar MYAPP = {};//constructorsmyapp.parent = function () {}; MYAPP. Child = function () {};//a variablemyapp.some_var = 1;//an object containermyapp.modules = {};//nested objectsmyapp.mod Ules.module1 = {}; MYAPP.modules.module1.data = {a:1, b:2}; MYAPP.modules.module2 = {};
The name of the global object, you can choose to use the name of the program, you can use the domain name, you can also use the company name. Usually the name of the global object is capitalized so that it looks more noticeable, but it is not a constant (constants are usually all uppercase). This pattern solves the problem of naming conflicts very well, because the variables used in different programs or in the company's code are organized into different global objects, so many JavaScript libraries use this method to organize the API. But this model also has some minor problems:
- Variables need to be used to knock more letters, JS files have become larger;
- There is only one global variable that makes it possible for all code to use it and modify it, which can take effect immediately;
- Long nested names make the parsing process of variables take longer.
The sandbox mode that will be introduced later will address these issues.
2. General-Purpose namespace functionsWhen the program becomes larger, it is no longer safe to declare it in a global object before using it: some properties and objects may already exist in the global object, and re-declare it will overwrite its original content, so we need to make a simple check when declaring the variable:
Unsafevar MyApp = {};//Betterif (typeof MyApp = = = = "undefined") { var myapp = {};} or shortervar MyApp = MyApp | | {};
The above check is simple and effective, but it is cumbersome: Before using MYAPP.modules.module2, you need to do 3 checks. Therefore, it is necessary to have a function called namespace (), which is checked every time a module or variable is declared:
Using a namespace functionmyapp.namespace (' MYAPP.modules.module2 ');//equivalent to://var MYAPP = {// modules: {/ / module2: {}// }//};
The following is a general implementation of the namespace () function:
var MyApp = MyApp | | {}; Myapp.namespace = function (ns_string) { var parts = ns_string.split ('. '), parent = MYAPP, i; Strip redundant leading global if (parts[0] = = = "MYAPP") { parts = parts.slice (1); } for (i = 0; i < parts.length; i + = 1) { //Create a property if it doesn ' t exist if (typeof parent[parts[i]] = = = "undefined") { Parent[parts[i]] = {}; } Parent = Parent[parts[i]]; } return parent;};
With the namespace () function above, we can do this:
Assign returned value to a local varvar module2 = myapp.namespace (' MYAPP.modules.module2 '); module2 = = MYAPP.modules.mo Dule2; true//Skip initial ' MYAPP ' Myapp.namespace (' modules.module51 ');//Long Namespacemyapp.namespace (' Once.upon.a.time.there.was.this.long.nested.property ');
This allows us to declare a very long nested namespace:
JavaScript Base Object creation mode namespace (Namespace) mode (022)