蛀牙--《设计模式---通往未来的很高的台阶之(六)》

来源:互联网 发布:男生淘宝图片 编辑:程序博客网 时间:2024/06/10 07:51

闭包和高阶函数

在js的版本的设计模式中,许多模式都可以用闭包和高阶函数来实现。。

闭包的形成与变量的作用域和变量的生存周期密切相关。

变量的作用域和生命周期在这里不做详细讲解。

上图 前方高能 啊啊啊啊啊啊啊
这里写图片描述

利用闭包我们可以许多奇妙的工作——介绍一个经典的例子

<html>    <body>         <div> 1 </div>         <div> 2 </div>         <div> 3 </div>         <div> 4 </div>         <div> 5 </div>    </body>    <script>         var nodes = document.getElementByTagName(' div ');         for(var i=0,len = nodes.length; i <len ; i++){             nodes[i].onclick = function(){                 alert(i)             }         }    </script></html>

运行这段代码会发现,无论你点击哪个div最后显示的都是5.这是为什么呢????

因为div节点绑定onclick事件是被异步触发的。当事件触发的时候,for循环早已经结束了,此时i值已经是5了。

想要解决就可以用闭包巧妙的吧每次循环的i的值都封闭起来。

 for(var i=0,len = nodes.length; i <len ; i++){     (function(i){             nodes[i].onclick = function(){                 alert(i)             }     })(i);}

闭包的作用之封装变量

写一个计算乘积的简单函数

var mult = function(){    var a = 1;    for(var i=0,l = arguments.length; i < l ; i++){        a = a * arguments[i];    }    return a;}

mult函数接受一些number类型的参数,并返回这些函数的乘积。现在我们觉得对于那些相同的参数来说,每次都进行计算是一种浪费。我们加入缓存机制来提高函数的性能

var cache = {};var mult = function(){    var args = Array.prototype.join.call(arguments,',');    if( cache[ args ] ){         return cache[ args ];    }    var a = 1;     for(var i=0,l = arguments.length; i < l ; i++){        a = a * arguments[i];    }    return cache[args] = a;};alert ( mult(1,2,3) ); //输出: 6alert ( mult(1,2,3) ); //输出: 6

上面代码cache变量和mult平行的暴露在全局作用域下。这很容易就出事情了,我们要把这个变量封闭起来,以避免这个变量在其他地方不小心被修改而引发错误。。

var mult = (function(){    var cache = {};    return function(){        var args = Array.prototype.join.call(arguments,',');        if( cache[ args ] ){             return cache[ args ];        }        var a = 1;         for(var i=0,l = arguments.length; i < l ; i++){            a = a * arguments[i];        }        return cache[args] = a;    }    })();

闭包和面向对象的设计

过程与数据的结合是形容面向对象中的“对象”时经常使用的表达。通常情况来讲,用面向对象的思想能实现的功能,用闭包也能实现。

var extent = function(){    var value = 0;    return{        call:function(){            value++;            console.log( value );        }    }}var extent = extent();extent.call();   //输出 1extent.call();   //输出 2       这是用闭包实现的   接下来用面向对象的的写法

var extent = {    value:0,    call:function(){        this.value++;        console.log(this.value);    }}extent.call();   //输出 1extent.call();   //输出 2       这是用面向对象实现的   

用闭包实现命令模式

在js的设计模式中,闭包运用非常广泛,举一个用闭包的方式实现的命令模式

<html>     <body>         <button id="execute">点击执行命令</button>         <button id="undo">点击执行命令</button>     </body>     <script>     var Tv = {         open:function(){            console.log('打开电视机');         },         colose.log('关闭电视机');     };     var OpenTvCommand = function(receiver){         this.receiver = receiver     };     OpenTvCommand.prototype.execute = function(){         this.receiver.open();   //执行打开电视的命令     };     OpenTvCommand.prototype.undo= function(){         this.receiver.close();   //执行关闭电视的命令     };     var setCommand = function(command){         document.getElementById('execute').onclick = function(){              command.execute();         }         document.getElementById('undo').onclick = function(){              command.undo();         }     };     setCommand( new OpenTvCommand( Tv ) );</script></html>

命令模式的意图是把请求封装为对象,从而分离请求的发起者和请求的接收者之间的耦合关系。。。


听取了老前辈的 建议 准备 再看一本书 在 更新

——–更新时间将推迟到大概7月初

——————–望请见谅

阅读全文
0 0
原创粉丝点击