Home  >  Article  >  Web Front-end  >  JavaScript design patterns security sandbox mode_js object-oriented

JavaScript design patterns security sandbox mode_js object-oriented

WBOY
WBOYOriginal
2016-05-16 18:19:151057browse

Namespace

JavaScript itself does not provide a namespace mechanism, so in order to avoid different function, object and variable names contaminating the global space, the usual approach is to create a unique namespace for your application or library. global object, and then add all methods and properties to this object.

Copy code The code is as follows:

/* BEFORE: 5 globals */
/ / constructors
function Parent() {}
function Child() {}
// a variable
var some_var = 1;
// some objects
var module1 = {} ;
module1.data = {a: 1, b: 2};
var module2 = {};
/* AFTER: 1 global */
// global object
var MYAPP = {};
// constructors
MYAPP.Parent = function() {};
MYAPP.Child = function() {};
// a variable
MYAPP.some_var = 1;
// an object
MYAPP.modules = {};
// nested objects
MYAPP.modules.module1 = {};
MYAPP.modules.module1.data = { a: 1, b: 2};
MYAPP.modules.module2 = {};

Code Listing 1: Traditional namespace mode


In this paragraph In the code, you create a global object MYAPP and attach all other objects and functions to MYAPP as properties.

Usually this is a better way to avoid naming conflicts, and it is used in many applications. project, but this approach has some disadvantages.

1. You need to add prefixes to all functions and variables that need to be added.
2. Because there is only one global object, this means that part of the code can modify the global object arbitrarily and cause the rest of the code to be passively updated.

Global Constructor

You can use a global constructor instead of a global object. We named this constructor Sandbox(). You can use this constructor to create objects. You can also pass a callback function as a parameter to the constructor. This callback function is an independent sandbox environment where you store your code.
Copy code The code is as follows:

new Sandbox(function(box){
 / / your code here...
});

Code Listing 2: Use of Sandbox


Let’s add some other features to the sandbox


1. You can not use the 'new' operator when creating a sandbox

2. The Sandbox() constructor accepts some additional configuration parameters, which define what is needed to generate the object The name of the module where we want the code to be more modular.


With the above features, let’s see how to initialize an object.


Listing 3 shows that you can create an object that calls the 'ajax' and 'event' modules without the need for the 'new' operator.


Copy code The code is as follows:

Sandbox(['ajax', 'event'], function (box){
  // console.log(box);
});

Code Listing 3: Pass the module name in the form of an array
Copy code The code is as follows:

Sandbox('ajax', 'dom', function(box){
  // console.log(box);
});

Listing 4: Passing the module name as a separate parameter

Listing 5 shows that you can use the wildcard character ' *' is passed to the constructor as a parameter, which means that all available modules are called. For convenience, if no module name is passed to the constructor as a parameter, the constructor will pass '*' as a default parameter.

Copy code The code is as follows:

Sandbox('*', function(box){
  // console.log(box);
});
Sandbox(function(box){
  // console.log(box);
});

Code Listing 5: Calling the available modules


Code Listing 6 shows that you can initialize the sandbox object multiple times, and you can even nest them without worrying about any interaction between them. Conflict.
Copy code The code is as follows:

Sandbox('dom', 'event', function(box){
// work with dom and event
  Sandbox('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
});

Code Listing 6: Nested Sandbox Instances

From the above examples It can be seen that using the sandbox mode, by wrapping all code logic in a callback function, you generate different instances according to the different modules required, and these instances work independently without interfering with each other, thus protecting the global naming. space.

Now let’s see how to implement the Sandbox() constructor.


Adding modules

Before implementing the main constructor, let’s see how to add Add modules to the Sandbox() constructor.

Since the Sandbox() constructor function is also an object, you can add an attribute called 'modules' to it. This attribute will be an object containing a set of key-value pairs, where each pair of key-value Key is the name of the module that needs to be registered, and Value is the entry function of the module. When the constructor is initialized, the current instance will be passed to the entry function as the first parameter, so that the entry function can add additional attributes to the instance. and methods.

In code listing 7, we added the 'dom', 'event', and 'ajax' modules.

Copy code The code is as follows:

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() {};
};

Code Listing 7: Registration module


Implementation structure Constructor

Code Listing 8 describes the method of implementing the constructor, with several key points:

1. We check whether this is an instance of Sandbox. If not, it proves that Sandbox has not been new operator call, we will call it again as a constructor.
2. You can add attributes to this inside the constructor, and you can also add attributes to the prototype of the constructor.
 3. The module name will be passed to the constructor in various forms such as arrays, independent parameters, wildcard characters '*', etc.
4. Please note that in this example we do not need to load the module from an external file, but in systems such as YUI3, you can only load the base module (often called a seed), and all other modules Will be loaded from an external file.
5. Once we know the required modules and initialize them, this means calling the entry function of each module.
 6. The callback function is passed into the constructor last as a parameter. It will use the latest generated instance and execute it at the end.
Copy code The code is as follows:

function Sandbox() {
   // 인수를 배열로 변환
   var args = Array.prototype.slice.call(arguments),
   // 마지막 인수는 콜백
     callback = args.pop(),
   // 모듈은 배열 또는 개별 매개변수로 전달될 수 있습니다.
     module = (args[0] && typeof args[0] === "string") ?
    args : args[0],
    i;
     // 함수가 호출되는지 확인하세요
    // 생성자로
   if (!(이 샌드박스 인스턴스)) {
     return new Sandbox(modules, callback);
  }
  // 필요에 따라 'this'에 속성을 추가합니다.
  this.a = 1;
  this.b = 2;
  // 이제 핵심 'this' 객체에 모듈을 추가합니다
  // 모듈이 없거나 "*"는 모두 "모든 모듈 사용"을 의미합니다
  if (!modules || 모듈 === '*') {
    모듈 = [];
    for (i in Sandbox.modules) {
      if (Sandbox.modules.hasOwnProperty(i)) {
        modules.push(i);
      }
     }
   }
  // 필수 모듈 초기화
  for (i = 0; i < module.length; i ) {
    Sandbox.modules[모듈[i ]](이것);
  }
  // 콜백 호출
  callback(this);
}
// 필요한 프로토타입 속성
Sandbox.prototype = {
  name: "My Application",
  version: "1.0",
  getName: function() {
    return this.name;
  }
};
Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn