【读书笔记】读《JavaScript模式》 - 对象创建模式
JavaScript是一种简洁明了的语言,其中并没有在其他语言中经常使用的一些特殊语法特征,比如命名空间(namespace)、模块(module)、包(package)、私有属性(private property),以及静态成员等语法。
当然,我们使用其他方式来模拟实现上述语法特征。
1 /** 2 * 1.命名空间模式 3 * 1>命名名称的选取:应用程序(QIANGBA)或库的名称(TIANLANG)、域名或公司(CYOU)名称 4 * 2>通用命名空间 5 * 注意名称覆盖的问题 6 * //不安全的代码 7 * var MYAPP = {}; 8 * //更好的代码 9 * if (typeof MYAPP === 'undefined') { 10 * var MYAPP = {}; 11 * } 12 * //或者用更短的语句 13 * var MYAPP = MYAPP || {}; 14 * 由此,我们不必太过担心加载顺序了。 15 * 2.声明依赖关系 16 * 3.私有属性和方法 17 * 1>私有成员(函数字面量来实现私有性) 18 * function Gadget() { //仅仅是一个包含私有数据的函数,我们可以用一个立即执行的匿名函数来替换之。 19 * //私有成员 20 * var name = 'iPod'; 21 * //公有函数 22 * this.getName = function () { //特权函数 23 * return name; 24 * } 25 * } 26 * 2>特权方法 27 * 3>私有性失效 28 * 4>对象字面量以及私有性 29 * var myobj = (function () { 30 * //私有成员 31 * var name = 'oh my baby'; 32 * //实现公有部分 33 * return { 34 * getName: function () { 35 * return name; 36 * } 37 * } 38 * })(); 39 * myobj.getName(); //oh my baby 40 * 5>原型和私有性 41 * 为了避免复制工作以及节省内存,可以将常用属性和方法添加到构造函数的prototype属性中。 42 * 6>将私有方法揭示为公共方法 43 * var myarray; 44 (function () { 45 var astr = '[Object Array]', 46 toString = Object.prototype.toString; 47 function isArray(a) { 48 return toString.call(a) === atr; 49 } 50 function indexOf(haystack, needle) { 51 var i = 0, 52 max = haystack.length; 53 for (; i < max; i++) { 54 if (haystack[i] === needle) { 55 return i; 56 } 57 } 58 return -1; 59 } 60 myarray = { 61 isArray: isArray, 62 indexOf: indexOf, //当公共indexOf方法发生了意外(如myarray.indexOf = null), 63 //但私有indexOf()方法仍然是安全的,此时inArray将继续正常运行 64 inArray: indexOf 65 } 66 })(); 67 */ 68 69 70 /** 71 * 4.模块模式 72 * 1>命名空间 73 * 2>即时函数 74 * 3>私有和特权成员 75 * 4>声明依赖 76 * 77 * ----------- (a)揭示模块模式 ------------- 78 * //(1)建立一个命名空间 79 MYAPP.namespace('MYAPP.utilities.array'); 80 //(2)定义模块 81 MYAPP.utilities.array = (function () { //用即时函数进行包围 82 //声明依赖 83 var uobj = MYAPP.utilities.object, 84 ulang = MYAPP.utilities.lang, 85 86 //私有属性 87 array_string = '[Object Array]', 88 ops = Object.prototype.toString, 89 90 //私有方法 91 isArray = function (a) { 92 return opts.call(a) === array_string; 93 }; 94 inArray = function (haystack, needle) { 95 var i = 0, 96 max = haystack.length; 97 for (; i < max; i++) { 98 if (haystack[i] === needle) { 99 return i; 100 } 101 } 102 return -1; 103 }; 104 105 //揭示公有API 106 return { 107 isArray: isArray, 108 indexOf: inArray 109 }; 110 111 })(); 112 113 ----------- (b)创建构造函数的模块 ------------- 114 MYAPP.namespace('MYAPP.utilities.array'); 115 MYAPP.utilities.array = (function () { //用即时函数进行包围 116 //声明依赖 117 var uobj = MYAPP.utilities.object, 118 ulang = MYAPP.utilities.lang, 119 120 //私有属性 121 Constr; 122 123 //公有API 124 Constr = function (o) { 125 this.elems = this.toArray(o); 126 }; 127 128 Constr.prototype = { 129 constructor: MYAPP.utilities.Array, 130 version: '2.0', 131 toArray: function (obj) { 132 for (var i = 0, a = [], len = obj.length; i < len; i++) { 133 a[i] = obj[i]; 134 } 135 return a; 136 } 137 }; 138 139 //返回要分配给新命名空间的构造函数 140 return Constr; 141 })(); 142 143 ----------- (c)将全局变量导入到模块中 ----------- 144 MYAPP.utilities.module = (function (app, global) { 145 //引用全局变量对象 146 //引用现在被转换成局部变量的全局应用程序命名空间对象(app) 147 })(MYAPP, this); 148 */ 149 150 /** 151 * 5.静态成员 152 * 1>公有静态成员 153 * //构造函数 154 var Gadget = function () {}; 155 //静态方法 156 Gadget.isShiny = function () { 157 return 'you bet'; 158 }; 159 //向该原型中添加普通方法 160 Gadget.prototype.setPrice = function (price) { 161 this.price = price; 162 }; 163 2>私有静态成员(普通闭包) 164 */ 165 166 /** 167 * 6.链模式 168 * return this;实现 169 */ 170 171 /** 172 * 7.method()方法 173 */