Javascript对象的创建模式 -- 深入了解Javascript
/* 一、模式1:命名空间(namespace) 优点:减少全局命名所需的数量,避免命名冲突或过度 */ // 更简洁的方式 var MYAPP = MYAPP || {}; //定义通用方法 MYAPP.namespace = function (ns_string) { var parts = ns_string.split('.'), parent = MYAPP, i; // 默认如果第一个节点是MYAPP的话,就忽略掉,比如MYAPP.ModuleA if (parts[0] === "MYAPP") { parts = parts.slice(1); } for (i = 0; i < parts.length; i += 1) { // 如果属性不存在,就创建 if (typeof parent[parts[i]] === "undefined") { parent[parts[i]] = {}; } parent = parent[parts[i]]; } return parent; }; /* 二、模式2:定义依赖 */ var myFunction = function () { // 依赖模块 var event = YAHOO.util.Event, dom = YAHOO.util.dom; // 其它函数后面的代码里使用局部变量event和dom }; /* 三、模式3:私有属性和私有方法 --通过闭包来实现 */ function Gadget() { var name = "123";//私有属性 //公有函数 this.getName = function () { return name; } } var myObj; // 通过自执行函数给myobj赋值 (function () { var name = "123";//自由对象 myObj = { //授权方法 getName: function () { return name; } } }()); /* 四、模式4:Revelation模式 --隐藏私有方法的模式 在外部先声明一个变量,然后在内部给变量赋值公有方法 */ var myarray; (function () { function isFunc() { } //通过赋值的方式,将上面所有的细节都隐藏了 myarray = { myFunc: isFunc }; }()); /* 五、模式5:链模式 链模式可以你连续可以调用一个对象的方法,比如obj.add(1).remove(2).delete(4).add(2)这样的形式,其实现思路非常简单,就是将this原样返回 */ var obj = { value: 1, increment: function () { return this; }, add: function () { return this; } } obj.increment().add(); /* 六、模式6:函数语法糖 函数语法糖是为一个对象快速添加方法(函数)的扩展,这个主要是利用prototype的特性 */ 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; }); /* 六、模式7:对象常量 对象常量是在一个对象提供set,get,ifDefined各种方法的体现,而且对于set的方法只会保留最先设置的对象,后期再设置都是无效的,已达到别人无法重载的目的 */ var constant = (function () { var ownProp = Object.prototype.hasOwnProperty, // 只允许设置这三种类型的值 allowed = { string: 1, number: 1, boolean: 1 }, consstants = {}; return { set: function (name, value) { if (this.isDefined(name)) { return false; } if (!ownProp.call(allowed, typeof value)) { return false; } constants[name] = value; return true; }, get: function () { return null; }, isDefined: function (name) { return ownProp.call(constants, name); } } }()); /* 六、模式8:沙盒模式 沙盒(Sandbox)模式即时为一个或多个模块提供单独的上下文环境,而不会影响其他模块的上下文环境,比如有个Sandbox里有3个方法event,dom,ajax,在调用其中2个组成一个环境的话,和调用三个组成的环境完全没有干扰 */ function Sandbox() { var args = Array.prototype.slice.call(arguments), //获取函数参数 callback = args.pop(),//最后一个参数,并从args除去 modules = (args[0] && typeof args[0] === "string") ? args : args[0], //除去最后一个参数,都为要选择的模块 i; //强制使用new修饰符 if (!(this instanceof Sandbox)) { return new Sandbox(modules, callback); } // 向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 += 1) { Sandbox.modules[modules[i]](this); } // 调用 callback callback(this); } 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.detachEvent = function () { }; }; Sandbox.modules.ajax = function (box) { box.makeRequest = function () { }; box.getResponse = function () { }; }; // 调用方式 Sandbox(['ajax', 'event'], function (box) { console.log(typeof (box.foo)); // 没有选择dom,所以box.foo不存在 }); Sandbox('ajax', 'dom', function (box) { console.log(typeof (box.attachEvent)); // 没有选择event,所以event里定义的attachEvent也不存在 }); Sandbox('*', function (box) { console.log(box); // 上面定义的所有方法都可访问 }); /* 六、模式9:静态成员 静态成员(Static Members)只是一个函数或对象提供的静态属性,可分为私有的和公有的 */ // 1. 公有静态函数 // 构造函数 var Gadget = function () { }; // 公有静态方法 Gadget.isShiny = function () { return "you bet"; }; // 原型上添加的正常方法 Gadget.prototype.setPrice = function (price) { this.price = price; }; // 调用静态方法 console.log(Gadget.isShiny()); // "you bet" // 创建实例,然后调用方法 var iphone = new Gadget(); iphone.setPrice(500); console.log(typeof Gadget.setPrice); // "undefined" console.log(typeof iphone.isShiny); // "undefined" Gadget.prototype.isShiny = Gadget.isShiny; console.log(iphone.isShiny()); // "you bet" // 2. 私有静态函数 --利用闭包特性实现 // a.第一种实现方式: var Gadget = (function () { // 静态变量/属性 var counter = 0; // 闭包返回构造函数的新实现 return function () { console.log(counter += 1); }; }()); // 立即执行 var g1 = new Gadget(); // logs 1 var g2 = new Gadget(); // logs 2 var g3 = new Gadget(); // logs 3 // b.第二种方式: var Gadget = (function () { // 静态变量/属性 var counter = 0, NewGadget; //新构造函数实现 NewGadget = function () { counter += 1; }; // 授权可以访问的方法 NewGadget.prototype.getLastId = function () { return counter; }; // 覆盖构造函数 return NewGadget; }()); // 立即执行 var iphone = new Gadget(); iphone.getLastId(); // 1 var ipod = new Gadget(); ipod.getLastId(); // 2 var ipad = new Gadget(); ipad.getLastId(); // 3