JavaScript模式读书笔记 第5章 对象创建模式
1,命名空间模式 namespace
<script>var myApp = {};//通过全局变量来实现命名空间maApp.Parent = function (){};myApp.Child = function(){};</script>
通用命名空间函数
<script>//不安全代码var myApp = {};//安全代码if(typeof myApp === "undefined"){var myApp = {};}//或者使用更短的语句var myApp = myApp || {};</script>
使用命名空间函数
<script>myApp.namespace("myApp.modules.module2");//等同于如下代码var myApp = {modules : {module2:{}}};</script>
<script>var myApp = myApp || {};myApp.namespace = function(ns_string){var parts = ns_string.split('.'), parent = myApp, i;if(parent[0] === "myApp"){parts = parts.slice(1);}for(i = 0; i < parts.length; i++){if(typeof parent[parts[i]] === "undefined"){parent = parent[parts[i]];}}return parent;};var modules2 = myApp.namespace("myApp.modules.module2");console.log(modules2 === myApp.modules.module2);myApp.namespace("modules.module2");</script>
2,声明依赖关系
js库通常是模块化且依据命名空间组织的。
var myFunction = function(){ var event = YAHOO.util.event, dom = YAHOO.util.Dom; }
3,私有属性和方法
JS并没有特殊的语法来表示私有。JS中所有对象的成员是公共的。
var myObj = {myProp : 1,getPro: function(){return this.myProp;}};console.log(myObj.myProp);console.log(myObj.getPro());
但是可以使用闭包实现成员私有化。
<script>function Gadget(){//私有成员var name = "iPoid";//共有函数this.getName = function(){return name;};}var toy = new Gadget();console.log(toy.name);//undefinedconsole.log(toy.getName);//iPoid</script>
私有性失效:因为涉及到引用传值,如果传递私有属性给外部,则外部可直接访问私有属性,如下:
<script>function Gadget(){//私有成员var specs = {screen_width: 320,screen_hight: 650,color: 'RED'};//共有函数this.getSpecs = function(){return specs;};}var toy = new Gadget(),specs = toy.getSpecs();specs.color = "GUESS";console.log(specs.screen_width);//320console.log(specs.color);//GUESSconsole.dir(toy.getSpecs());</script>
4,对象字面量以及私有属性
<script>var myObj = (function(){var name = "name";return {getName: function(){return name;}};}());console.log(myObj.getName());//name</script>
5,原型和私有性
通过prototype可以动态的给对象添加属性和方法。
<script>function Gadget(){var name = "Ipod";this.getName = function(){return name;};}Gadget.prototype = (function(){var browser = "others";return{getBrowser: function(){return browser;}};}());var toy = new Gadget();console.log(toy.getName());//nameconsole.log(toy.getBrowser());//others</script>
6,将私有方法揭示为公共方法
通过全局变量可以将匿名函数的私有方法公开。
<script>var myArray;(function(){var astr = "[object Array]",toString = Object.prototype.toString;function isArray(s){return toString.call(s) === astr;}function indexOf(haystack, needle){var i = 0,max = haystack.length;for(; i < max; i+= 1){if(haystack[i] === needle){return i;}}return -1;}myArray = {isArray: isArray,indexOf: indexOf,inArray: indexOf};console.log(myArray.isArray([1, 2]));//trueconsole.log(myArray.isArray({0 : 1}));//falseconsole.log(myArray.indexOf(["a", "b"], "a"));//0console.log(myArray.indexOf(["a", "b"], "d"));//-1}());console.log(myArray.indexOf(["a", "b"], "a"));//0console.log(myArray.indexOf(["a", "b"], "d"));//-1</script>
7,模块模式
模块模式通过命名空间,完成函数变量定义和使用。
<script>myApp.namespace("myApp.util.array");myApp.util.array = (function(){var uobj = myApp.util.object,ulang = myApp.util.lang,array_string = "[object Array]",ops = Object.prototype.toString;return {inArray: function(needle, haystack){for(var i = 0, max = haystack.length; i < max; i+= 1){if(haystack[i] === needle){return true;}}},isArray: function(s){return ops.call(a) === array_string;}};}());</script>
通过揭示模式暴漏想暴漏的方法。
<script>myApp.namespace("myApp.util.array");myApp.util.array = (function(){var uobj = myApp.util.object,ulang = myApp.util.lang,array_string = "[object Array]",ops = Object.prototype.toString;inArray: function(needle, haystack){for(var i = 0, max = haystack.length; i < max; i+= 1){if(haystack[i] === needle){return true;}}},isArray: function(s){return ops.call(a) === array_string;};return {isArray: isArray,indexOf: inArray};}());</script>
创建构造函数的模块
<script>myApp.namespace("myApp.util.array");myApp.util.array = (function(){var uobj = myApp.util.object,ulang = myApp.util.lang;Constr;Constr = function(o){this.elements = this.toArray(o);};//共有API原型Constr.prototype = {constructor: myApp.util.array,version: "2.0",toArray: function(obj){for(var i = 0, a= [], len = obj.length; i < len; i+= 1){a[i] = obj[i];}return a;}};//返回要分配给新命名空间的构造函数return Constr;});var arr = new myApp.util.array([obj]);</script>
8,将全局变量导入到模块中
<script>MYAPP.util.module = (function(app, global){//}(MYAPP, this));</script>
9,沙箱模式
沙箱模式解决命名空间模式的如下特点:
-1,对单个全局变量的依赖变成了对应用程序的全局变量依赖。在命名空间模式中,是没有办法使用同一个应用程序或库的两个版本在同一页面中,因为这两者都需要同一个全局符号名。
-2,对这种以点分割的名字来说,需要输入更长的字符,同时解析时需要更长的时间。如:myapp.a.b.c.d
沙箱模式提供了一个可用于模块运行的环境,且不会对其他模块和沙箱造成影响。
10,全局构造函数
最基础的使用如下图所示
<script>new Sandbox(function(box){//write your code});</script>
通过以下两种方式扩展属性:
-1,在创建对象的时候不实用new操作符。
-2,Sandbox()狗仔函数可以接受一个额外的配置参数,其中改参数制订了对象事例所需要的模块名。
<script>Sandbox(['ajax', 'event'], function(box){//your code});</script>
或者,
<script>Sandbox('ajax', 'event', function(box){//your code});</script>
一个沙箱中可以继续使用一个沙箱模块。
<script>Sandbox('dom', 'event', function(box){//your codeSandbox('ajax', function(box){//your cide})//此处无法获取ajax});</script>
11,增加模块
<script>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 = "mmmmm";box.attachEvent = function(){};box.dettachEvent = function(){};};Sandbox.modules.ajax = function(box){box.makeRequest = function(){};boix.getResponse = function(){};}</script>
12,实现构造函数
<script>function Sandbox(){//将参数转为一个数组var args = Array.prototype.slice.call(arguments),//最后一个参数是回调函数callback = args.pop(),//模块可以做为一个数组传递,或作为单独的参数传递modules = (args[0] && typeof args[0] === "string") ? args : args[0],i;//确保该函数做为狗仔函数被调用if(! (this instanceof Sandbox)){return new Sandbox(modules, callback);}//向this添加属性this.a = 1;this.b = 2;//向this对象添加模块//不制定模块或指定“*”都表示使用所有模块if(!modules || modules === "*"){for(i in Sandbox.modules){if(Sandbox.modules.hasOwnProperty(i)){moduls.push(i);}}}//初始化模块for(i = 0; i < modules.length; i+= 1){Sandbox.modules[[moduls[i]]](this);}callback(this);}Sandbox.prototype = {name: "My Application",version: "1.00",getName: function(){return this.name;}};</script>
以上代码的关键部分:
-1,存在一个类型的检查语句,检查this是否为Sandbox的实例。
-2,可以在该构造函数中将一些属性添加到this中。
-3,所需的模块可以魔窟名称数组的形式传递。
13,公有静态成员
<script>//构造函数var Gadget = function(){};//静态方法Gadget.isShiny = function(){return "Static Method!";};//原型添加方法Gadget.prototype.setPrice = function(price){this.price = price;};console.log(Gadget.isShiny());//Static Method!var iphone = new Gadget();iphone.setPrice(500);console.log(typeof Gadget.setPrice);//undefinedconsole.log(typeof iphone.isShiny);//undefinedGadget.prototype.isShiny = Gadget.isShiny;console.log(iphone.isShiny());//Static Method!</script>
14,私有静态成员
-1,以同一个构造函数创建的所有对象共享该成员
-2,构造函数外部不可访问该成员。
<script>var Gadget = (function(){var counter = 0;return function(){console.log(counter += 1);}}());//立即执行var g1 = new Gadget();//1var g2 = new Gadget();//2</script>
15,链模式
如:
myObj.method1("11").method2("w").method3();
16,method方法
var Person = function(name){this.name = name;}.method("getName", function(){return this.name;});
欢迎转载,但转载请注明原文链接[博客园: http://www.cnblogs.com/jingLongJun/]
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。
[CSDN博客:http://blog.csdn.net/mergades]。
如相关博文涉及到版权问题,请联系本人。

浙公网安备 33010602011771号