锁定老帖子 主题:javascript 闭包的一个例子
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (3)
|
|
---|---|
作者 | 正文 |
发表时间:2011-03-07
最后修改:2011-03-07
<html> </script>
以上代码将会弹出hello窗口
以上代码实际上是定义了一个匿名函数,并且调用了该匿名函数 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-03-09
闭包:可以用一个概念本身来定义该概念。
LZ的例子似乎有那么点不恰当。。。 |
|
返回顶楼 | |
发表时间:2011-03-09
虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() { var a = 3; return function() { alert(a); }; })(); closure();//3 这个或许可以再深入一点? |
|
返回顶楼 | |
发表时间:2011-03-09
闭包是“带有自由变量的函数”。楼上的例子是闭包(带有自由变量a),但楼主的例子不是闭包,只是“函数字面量”。
|
|
返回顶楼 | |
发表时间:2011-03-09
呵呵,是我理解错了 ,谢谢各位指正
|
|
返回顶楼 | |
发表时间:2011-03-09
mabusyao 写道 闭包:可以用一个概念本身来定义该概念。
LZ的例子似乎有那么点不恰当。。。 谢谢,指正 ,是我理解错了 |
|
返回顶楼 | |
发表时间:2011-03-10
superobin 写道 虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() { var a = 3; return function() { alert(a); }; })(); closure();//3 这个或许可以再深入一点? 我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢? var closure = function() { var a = 3; return function() { alert(a); }; }; closure();//3 |
|
返回顶楼 | |
发表时间:2011-03-10
suiye007 写道 superobin 写道 虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() { var a = 3; return function() { alert(a); }; })(); closure();//3 这个或许可以再深入一点? 我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢? var closure = function() { var a = 3; return function() { alert(a); }; }; closure();//3 下面的代码调用closure()得到的结果不是3,而是一个闭包。上面的代码closure本身就是闭包,调用这个闭包得到结果3 |
|
返回顶楼 | |
发表时间:2011-03-11
kidneyball 写道 suiye007 写道 superobin 写道 虽然勉强可以算是闭包,但是基本没有体现闭包的特性额
var closure = (function() { var a = 3; return function() { alert(a); }; })(); closure();//3 这个或许可以再深入一点? 我不明白你的代码与下面的代码有什么区别呢,或简单的说是优点呢? var closure = function() { var a = 3; return function() { alert(a); }; }; closure();//3 下面的代码调用closure()得到的结果不是3,而是一个闭包。上面的代码closure本身就是闭包,调用这个闭包得到结果3 谢谢,发现问题所在了,我取的时候也是3,是New一个对象,然后,apply的,直接调用确实不是,不过,我有点不太明白什么时候要用闭包,什么时候不要用,虽然我的程序中闭包用得也比较的多,那是不得已的时候才用的 ,能给点经验吗? |
|
返回顶楼 | |
发表时间:2011-03-11
最后修改:2011-03-11
suiye007 写道 谢谢,发现问题所在了,我取的时候也是3,是New一个对象,然后,apply的,直接调用确实不是,不过,我有点不太明白什么时候要用闭包,什么时候不要用,虽然我的程序中闭包用得也比较的多,那是不得已的时候才用的 ,能给点经验吗? 往大里说,闭包是一种跟面向对象技术同样层面的“把数据与操作进行绑定”的技术。只不过面向对象是基于数据(对象实体)来封装操作(对象方法),而闭包是基于操作(函数)来封装数据(自由变量) 往小里说,使用闭包的最常见的场景是用来模拟“柯里化”。所谓柯里化,就是假如你有一个带有多个参数的函数,你可以通过指定其中某些参数的值,来产生参数较少的新函数。例如: function f(x,n) { //求幂 var result = 1; for (var i = 0; i <n; i++) {result *= x;} return result; } function currying(n) { return function(x) {return f(x,n);}; } var square = currying(2); var cube = currying(3); alert(squre(2)); //4 alert(cube(2)); //8 柯里化有两个用处, 1是你可以为柯里化之后的方法命名,更有效地表达业务逻辑。 2是为回调函数提供接口上缺失但在绑定时可以确定的运行期信息。就是当回调函数接口无法提供满足业务需求的足够上下文信息,而这些信息在运行期注册回调函数时可以确定。这时我们在编程时可以设计出具有额外接口参数的回调函数,在注册回调函数时运用Currying创建出携带有这些信息的符合接口规范的新函数。 例如: btn1.onclick=function() {....;n=n*3;....}; btn2.onclick=function() {....;n=n*6;....}; //...部分与btn1一致 btn3.onclick=function() {....;n=n*7;....}; //...部分与btn1一致 其中3,6,7是根据业务需求硬编码的,没有规律(也就是说在你绑定onclick时才知道到底是用3,6,还是7)。为了把回调函数抽象统一起来,如果不用闭包,你就必须把这个绑定期的信息缓存起来,以便在回调时可以使用: btn1.x = 3; btn2.x = 6; btn2.x = 7; function click() {...,n=n*this.x,...}; btn1.onclick=click; btn2.onclick=click; btn3.onclick=click; 这种代码一多就搞得很乱,而且缓存信息的安全性也无法保证(很可能在回调之前就被其他人误操作修改了)。如果用闭包你可以: function makeClick(x) {return function(x) {...;n=n*x;...}}; btn1.onclick=makeClick(3); btn2.onclick=makeClick(6); btn3.onclick=makeClick(7); 还有就是你可以通过闭包为某个函数实例保存一些内部的全局状态,这与面向对象类似,但是写起来比较方便简洁,避免了多余的传参或全局变量。例如: function makeCounter() { var a = 0; return function() {return ++a;); } var counter1 = makeCounter(); var counter2 = makeCounter(); counter1(); counter1(); alert(counter1()); //3 counter2(); alert(counter2()); //2 代码是随手打的,没有测试,只是表达一下意思。 |
|
返回顶楼 | |