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     }

  

关于使用接口,自己权衡利弊

  

三:封装和信息隐藏:

  后续补充----------请期待........

    

posted @ 2015-08-30 12:59  不得不爱xxy  阅读(575)  评论(0编辑  收藏  举报