闭包和高阶函数
在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) ); //输出: 6
alert ( 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(); //输出 1
extent.call(); //输出 2 这是用闭包实现的 接下来用面向对象的的写法
var extent = {
value:0,
call:function(){
this.value++;
console.log(this.value);
}
}
extent.call(); //输出 1
extent.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月初
——————–望请见谅