沙箱模式:
- 解决空间命名模式的几个缺点:
- 命名空间模式中无法同时使用一个应用程序或库的两个版本运行在同一个页面中,因为两者需要相同的全局符号;
- 以点分割,需要输入更长的字符,解析时间也更长;
- 全局构造函数 //在命名空间模式中,可以使用全局对象;在沙箱模式中主要使用全局构造函数
- 添加特征:
- 强制new模式
- 接受额外配置参数,指定对象实例所需的模块名;
- 例子
Sandbox(['ajax','event'], function (box) {}); -------------- Sandbox('ajax', 'event', function (box) {}); --------------- 可以设置参数*表示所有可用的模块;或者不设参数来默认 Sandbox(*, function (box) {}); Sandbox(function (box) {});
- 添加特征:
- 增加模块: 通过增加静态属性
Sandbox.modules = {}; Sandbox.modules.dom = function(box) { box.getElement = function(){}; box.getStyle = function(){}; box.foo = 'bar'; } Sandbox.modules.event = function(box) { //如果需要访问Sandbox原型 box.constructor.prototype.m = 'mmm'; box.attachEvent = function() {}; box.dettachEvent = function() {}; } Sandbox.modules.ajax = function(box) { box.makeRequest = function() {}; box.getRequest = function() {}; }
- 实现构造函数
function Sandbox() { //将参数转化为数组 var args = Array.prototype.slice.call(arguments), //最后一个是回调函数 callback = args.pop(), //提取数组或单独的模块 modules = (args[0] && typeof args[0] === 'string') ? args : args[0], i; //强制new模式 if(!(this instanceof Sandbox)) { return new Sandbox(modules, callback); } //向this添加需要的属性 this.a = 1; this.b = 2; //向this对象添加模块 //不指定模块或‘*’都表示使用所有模块 if(!modules || modules === '*') { modules = []; for(i in Sandbox.modules) { if (Sandbox.modules.hasOwnProperty(i)) { modules.push(i); } } } //初始化所需模块 for(i = 0; i < modules.length; i++) { Sandbox.modules[modules[i]](this); } callback(this); } //添加需要的原型属性 Sandbox.prototype = { name: 'My Application', version: '1.0', getName: function() { return this.name; } }
静态成员: 静态属性和方法就是那些从一个实例到另一个实例都不会发生改变的属性和方法
- 公有静态成员:
var Gadget = function(price) { this.price = price; }; //静态方法 Gadget.isShiny = function () { var msg = 'you bet'; if(this instanceof Gadget) { msg += ', it costs $' + this.price + ' !'; } return msg; }; Gadget.prototype.isShiny = function() { return Gadget.isShiny.call(this); } var a = new Gadget('499.99'); a.isShiny();
- 私有静态成员:
- 同一个构造函数创建的所有对象共享该成员;
- 构造函数外部不能访问该成员;
var Gadget = (function () { //静态变量/属性 var counter = 0, NewGadget; NewGadget = function () { counter++; } //特权方法 NewGadget.prototype.getLastId = function () { console.log(counter); } // return NewGadget; })(); var g1 = new Gadget(); g1.getLastId();
对象常量:
- 通用实现方法
var constant = (function () { var constants = {}, ownProp = Object.prototype.hasOwnProperty, allowed = { string: 1, number: 1, boolean: 1 }, prefix = (Math.random() + '_').slice(2); return { set: function(name, value) { if(this.isDefined(name)) { return false; } if(!ownProp.call(allowed, typeof value)) { return false; } constants[prefix + name] = value; return true; }, isDefined: function (name) { return ownProp.call(constants, prefix + name); }, get: function (name) { if(this.isDefined(name)) { return constants[prefix + name]; } return null; } } })();
- set(name, value);
- isDefined(name);
- get(name);
链模式:用于调用对象的方法,当创建的方法返回值是无任何意义的值时,可以使它们返回this;
- 优点:代码更简洁,;可以分割函数创建简短,具有特定功能的函数,而不是创建实现太多功能的函数;
- 缺点:难以调试
method方法:语法糖的一种
例子:
if(typeof Function.prototype.method !== 'function') { Function.prototype.method = function (name, implementation) { this.prototype[name] = implementation; return this; } }; var Person = function (name) { this.name = name; } .method('getName', function () { return this.name; }) .method('setName', function (name) { this.name = name; return this; }); var a = new Person('Adam');