【IT168技术文档】
闭包意味着内层的函数可以引用存在于包绕它的函数的变量,即使外层的函数的执行已经终止。这一特殊的论题可能是非常强大又非常复杂的。我强烈推荐你们参考本节后面将提及的站点,因为它有一些关于闭包这一话题的精彩的信息。
我们先来看程序2-13所示的闭包的两个简单例子。
程序2-13. 闭包改善的代码清晰性的两例
使用闭包的概念,完全可能的把这种混乱的代码清理掉。第一个例子很简单;有一个回调函数在调用setTimeout函数以后1000微秒以后被调用,而它仍引用了变量obj(定义在全局范围,指向id为"main"的元素)。定义的第二个函数,delayedAlert,展示了一种解决出现的 setTimeout混乱的方案,以及函数作用域内可以有闭包的能力。//得到id为"main"的元素 var obj = document.getElementById("main"); //改变它的边框样式 obj.style.border = "1px solid red"; //初始化一个1秒钟以后被调用的回调函数 setTimeout(function(){ //此函数将隐藏该元素 obj.style.display = 'none'; }, 1000); //用来延迟显示消息的通用函数 function delayedAlert( msg, time ) { //初始化一个被封套的函数 setTimeout(function(){ //此函数使用了来自封套它的函数的变量msg alert( msg ); }, time ); } //调用函数delayedAlert,带两个参数 delayedAlert( "Welcome!", 2000 ); 第一个对setTimeout的函数调用,展示了一个的JavaScript新手遇到问题的通俗的例子。在JavaScript新手的程序里像这样的代码时常可以看到: setTimeout("otherFunction()", 1000); //或者甚至 setTimeout("otherFunction(" + num + "," + num2 + ")", 1000);
你们应该可以发现,当在代码中使用这种简单的闭包时,你所写的东西的清晰性将会提高,免于陷入语法的迷雾之中。
我们来看一个闭包可能带来的有有趣的副作用。在某些函数化的编程语言里,有一个叫做currying的概念。本质上讲,currying是就是为函数的一些参数预填入值,创建一个更简单的新函数的方法。代码2-14里有一个简单的currying的例子,创建了向另一个函数预填一个参数而得的新函数。
代码2-14. 使用闭包的函数currying
//生成做加法的新函数的函数 function addGenerator( num ) { //返回一个简单函数用来计算两个数的加法, //其中第一个数字从生成器中借用 return function( toAdd ) { return num + toAdd }; } //addFive现在是接受一个参数的函数, //此函数将给参数加5,返回结果数字 var addFive = addGenerator( 5 ); //这里我们可以看到,当传给它参数4的时候 //函数addFive的结果为9 alert( addFive( 4 ) == 9 );