JavaScript设计模式——前奏
1 Function.prototype.method = function(name,fn){ 2 this.prototype[name] = fn; 3 } 4 var Anim = function(){ 5 //---- 6 }; 7 Anim.method("start",function(){ 8 //---- 9 }) 10 Anim.method("stop",function(){ 11 //---- 12 })
1 //方法的链式调用 2 3 Function.prototype.method = function(name,fn){ 4 this.prototype[name] = fn; 5 return this; 6 } 7 var Anim = function(){ 8 //---- 9 }; 10 Anim. 11 method("start",function(){ 12 //---- 13 }). 14 method("stop",function(){ 15 //---- 16 })
一:首先,再回顾一下JavaScript:
1.数据类型
原始类型:布尔型、数值型、字符串类型
在就包括:对象类型(数组是一种特殊的对象)、函数类型
最后就是:空类型(null)、未定义类型(undefind)
注意:原始类型按值传送,其他数据类型则按引用传送。
toString() 数值或者布尔类型转换成字符串类型。
parseInt() parseFloat() 把字符串转换成数值。
双重非(var bool = !! num;) 把字符串转换成布尔值。
2. 闭包:
闭包是一个受保护的变量空间,由内嵌函数生成。JavaScript具有函数级的作用域。这意味着函数内部的变量函数外部不能访问。JavaScript的作用域是词法性质的。这意味着函数运行在定义它的作用域中,而不是在调用它的作用域中。这样就可以创建私有变量:
1 var baz; 2 (function(){ 3 var foo = 1; 4 var bar = 2; 5 baz = function(){ 6 retrun foo*bar; 7 } 8 }) 9 10 baz();
3. 对象的易变性:
对实例化的对象进行扩展。比如给一个实例加一个方法或者给一个函数加一条属性。
与之相关的还有内省的概念:可以在运行时检查对象所具有的属性和方法,还可以使用这种信息动态实例化类和执行其方法。(这种技术称为反射)---(我对此的概念有点模糊,日后补充。嘿嘿......)
二:接口:
JavaScript模仿接口的三种方法:注释法、属性检查法、鸭式辨型法。
1.注释法:
注释法简单,但是,嘿嘿。效果最差。
1 /* 2 interface jk{ 3 function add(child); 4 function remove(child); 5 function get(child); 6 } 7 */ 8 var sx = function(){ 9 //------ 10 } 11 sx.prototype.add = function(){ 12 //------ 13 } 14 sx.prototype.remove = function(){ 15 //------ 16 } 17 sx.prototype.get = function(){ 18 //------ 19 }
看懂了吧。。加个注释你就想让人家按你的规范了。我才不呢。。。。任性,反正不安你的来不会报错,而且对测试和调试没什么卵用!!
2.属性检查法:
1 /* 2 interface jk{ 3 function add(child); 4 function remove(child); 5 function get(child); 6 } 7 interface jk_two{ 8 function save(child); 9 } 10 */ 11 var sx = function(id,method,action){ 12 this.impletementsInterfaces = ['jk','jk_two']; 13 } 14 15 function addForm(formInstance){ 16 if(!impletements(formInstance,'jk','jk_two')){ 17 throw new Error("Object does not implement a required interface.") 18 } 19 } 20 21 function impletements(object){ 22 for(var i = 1; i<arguments.length; i++){ 23 var interfaceName = arguments[i]; 24 var interfaceFound = fale; 25 for(var j = 0; j<object.impletementsInterfaces.length; j++){ 26 if(object.impletementsInterfaces[j] == interfaceName){ 27 interfaceFound = true; 28 break; 29 } 30 } 31 32 if(!interfaceFound) 33 return false; 34 } 35 return true; 36 }
3.鸭式辨型法:
1 var Composite = new Interface('Composite',['add','remove','getChild']); 2 var FormItem = new Interface('FormItem',['save']); 3 4 var CompositeForm = function(id, method, action){ 5 //....... 6 } 7 8 //....... 9 10 function addForm(formInstance){ 11 ensureImplements(formInstance, Composite, FormItem); 12 //如果有一个接口的方法没有被继承,这个方法会抛出一个错误。。。。 13 }
接下来说一下结合第一种和第三种方法的接口实现:
1 var Composite = new Interface('Composite',['add','remove','getChild']); 2 var FormItem = new Interface('FormItem',['save']); 3 4 var CompositeForm = function(id, method, action){ 5 //....... 6 } 7 8 //....... 9 10 function addForm(formInstance){ 11 Interface.ensureImplements(formInstance, Composite, FormItem); 12 //如果有一个接口的方法没有被继承,这个方法会抛出一个错误。。。。 13 } 14 15 //----下面是Interface类 16 17 var Interface = function (name, methods) { 18 if(arguments.length !=2){ 19 throw new Error("Interface constructor called with " + arguments.length + "arguments, but expected exactly 2.") 20 } 21 22 this.name = name; 23 this.methods = []; 24 for(var i = 0, len = methods.length; i < len; i++){ 25 if(typeof methods[i] !== 'string'){ 26 //接口构造函数希望将方法名称传递给字符串 27 throw new Error("Interface constructor expects method names to be" + "passed in as a string") 28 } 29 this.methods.push(methods[i]) 30 } 31 }; 32 //静态类方法 33 Interface.ensureImplements = function(object){ 34 if(arguments.length < 2){ 35 //函数 interface.ensureimplements 称有2个参数,但预计至少2。 36 throw new Error("Function Interface.ensureImplements called with " + arguments.length + "arguments, but expected at least 2.") 37 } 38 for(var i = 1, len = arguments.length; i < len; i++){ 39 var interface = arguments[i]; 40 if(interface.constructor !== Interface){ 41 throw new Error("Function Interface.ensureImplements expects arguments" + "two and above to be instances of Interface.") 42 } 43 for(var j = 0, methodsLen = interface.methods.length; j < methodsLen; j++){ 44 var method = interface.methods[j]; 45 if(!object[method] || typeof object[method] !== 'function'){ 46 //没有继承 xx 接口,方法 xx 没有发现 47 throw new Error("Function Interface.ensureImplements:object does not implement the " + interface.name + " interface.Method" + method + " was not found.") 48 } 49 } 50 } 51 }
关于使用接口,自己权衡利弊
三:封装和信息隐藏:
后续补充----------请期待........