Sandbox mode is common in YUI3core, which uses the same Constructor)
The Sandbox mode is common in YUI3 core. It is an instance object that uses the same Constructor to generate independent and independent of each other (self-contained, the method to avoid Global Object contamination.
Namespace
JavaScript itself does not provide a namespace mechanism. To avoid global space pollution caused by different functions, objects, and variable names, the common practice is to create a unique global object for your application or library, and then add all methods and attributes to this object.
Code List 1: Traditional namespace Mode
/* BEFORE: 5 globals */// constructorsfunction Parent() {}function Child() {}// a variablevar some_var = 1;// some objectsvar module1 = {};module1.data = {a: 1, b: 2};var module2 = {};/* AFTER: 1 global */// global objectvar MYAPP = {};// constructorsMYAPP.Parent = function() {};MYAPP.Child = function() {};// a variableMYAPP.some_var = 1;// an objectMYAPP.modules = {};// nested objectsMYAPP.modules.module1 = {};MYAPP.modules.module1.data = {a: 1, b: 2};MYAPP.modules.module2 = {};
In this Code, you have created a global object MYAPP and attached all other objects and functions as attributes to MYAPP.
This is usually a better way to avoid name conflicts. It is applied to many projects, but this method has some disadvantages.
- You must add a prefix to all functions and variables to be added.
- Because there is only one global object, this means that some code can modify the Global Object and cause passive updates of other codes.
Global Constructor
You can use a global constructor instead of a Global Object. We name this constructor Sandbox (). You can use this constructor to create an object, you can also pass a callback function as a parameter for the constructor, which is an independent sandbox environment where you store code.
Code List 2: Sandbox usage
new Sandbox(function(box){// your code here...});
Let's add some other features to the sandbox.
- You do not need to use the 'new' operator when creating a sandbox.
- The Sandbox () constructor accepts some additional configuration parameters that define the name of the module required for generating the object, and we want the code to be more modular.
With the above features, let's see how to initialize an object.
Code listing 3 shows that you can create an object that calls the 'ajax 'and 'event' modules without the 'new' operator.
Code List 3: Passing module names in the form of Arrays
Sandbox(['ajax', 'event'], function(box){// console.log(box);});
Code list 4: Passing module names as independent parameters
Sandbox('ajax', 'dom', function(box){// console.log(box);});
Code List 5 shows that you can pass the wildcard '*' as a parameter to the constructor, which means to call all available modules for convenience, if no module name is passed as a parameter to the constructor, the constructor uses '*' as the default parameter.
Code List 5: available modules used for calling
Sandbox('*', function(box){// console.log(box);});Sandbox(function(box){// console.log(box);});
Code Listing 6 shows that you can initialize sandbox objects multiple times, or even nest them without worrying about any conflict between them.
Code List 6: Nested sandbox instances
Sandbox('dom', 'event', function(box){// work with dom and eventSandbox('ajax', function(box) {// another sandboxed "box" object// this "box" is not the same as// the "box" outside this function//...// done with Ajax});// no trace of Ajax module here});
From the above examples, we can see that the sandbox mode is used to wrap all the code logic in a callback function. You can generate different instances based on different modules, these instances do not interfere with each other and work independently, thus protecting the global namespace.
Now let's see how to implement this Sandbox () constructor.
Add Module
Before implementing the main constructor, let's take a look at how to add modules to the Sandbox () constructor.
Because the Sandbox () constructor function is also an object, you can add an attribute named 'modules' to it. This attribute will be an object containing a set of key-value pairs, each Key-Value pair is the module name to be registered, and Value is the entry function of the module, when the constructor initializes, the current instance will be passed to the entry function as the first parameter, so that the entry function can add additional attributes and methods for the instance.
In code listing 7, we added the 'dom ', 'event', and 'ajax' modules.
Code List 7: Registration Module
Sandbox.modules = {};Sandbox.modules.dom = function(box) {box.getElement = function() {};box.getStyle = function() {};box.foo = "bar";};Sandbox.modules.event = function(box) {// access to the Sandbox prototype if needed:// box.constructor.prototype.m = "mmm";box.attachEvent = function(){};box.dettachEvent = function(){};};Sandbox.modules.ajax = function(box) {box.makeRequest = function() {};box.getResponse = function() {};};
Implementation Constructor
Code listing 8 describes how to implement the constructor. The key points are as follows:
- Check whether this is a Sandbox instance. If not, it proves that Sandbox is not called by the new operator. We will re-call it as a constructor.
- You can add properties for this in the constructor, or you can add properties for the constructor prototype.
- The module name is passed to the constructor in the form of arrays, independent parameters, and wildcards.
- Note that in this example, we do not need to load modules from external files, but in YUI3, you can only load basic modules (usually called seed )), all other modules are loaded from external files.
- Once we know the required modules and initialize them, this means that the entry functions of each module are called.
- The callback function is passed into the constructor as a parameter. It uses the newly generated instance and runs it at the end.
Code List 8: implement the Sandbox Constructor
《script》function Sandbox() {// turning arguments into an arrayvar args = Array.prototype.slice.call(arguments),// the last argument is the callbackcallback = args.pop(),// modules can be passed as an array or as individual parametersmodules = (args[0] && typeof args[0] === "string") ?args : args[0],i;// make sure the function is called// as a constructorif (!(this instanceof Sandbox)) {return new Sandbox(modules, callback);}// add properties to 'this' as needed:this.a = 1;this.b = 2;// now add modules to the core 'this' object// no modules or "*" both mean "use all modules"if (!modules || modules === '*') {modules = [];for (i in Sandbox.modules) {if (Sandbox.modules.hasOwnProperty(i)) {modules.push(i);}}}// init the required modulesfor (i = 0; i < modules.length; i++) {Sandbox.modules[modules[i]](this);}// call the callbackcallback(this);}// any prototype properties as neededSandbox.prototype = {name: "My Application",version: "1.0",getName: function() {return this.name;}};《script》
This article is available at http://www.nowamagic.net/librarys/veda/detail/344.