js函数闭包学习贴
前几天看了《javascript语言精髓与编程实践》对函数闭包的讲解,很有感触,跟大家分享一下。
其实js支持函数闭包的主要原因是因为js需要函数能够保存数据。这里的保存数据是只函数在运行结束以后函数内变量的值也会进行保存。至于为什么js需要在函数内可以保存数据,那就是js是一种函数式语言。在函数内保存数据是函数式语言的一大特征。上代码:
- JScript code
var getValue,setValue; function test(){var value=100;getValue=function (){ return value;}setValue =function (x){ value=x;} }test();alert(getValue());//输出100setValue(200);//设置valuealert(getValue());//输出200上例表明函数内部可以保存数据,而这是通过函数闭包实现的。
函数闭包是一个运行时的概念。函数闭包对应函数实例。而一个函数定义可能会对应多个函数实例。那么在什么情况下会返回不同的函数实例呢?
- JScript code
function getFunction(){return function (){ alert(value);}}var func1=getFunction();var func2=getFunction();alert(func1==func2)//输出false,表示是两个不同的函数应用。很多情况下使用的都是不同的函数实例。比如在使用函数作为构造函数时。其实在不同情况下返回不同的函数实例也是可以解释的。后面我们会说到。
每一个函数实例对应至少一个函数闭包。对应一个闭包居多。故先说明对应一个函数闭包。
基本一个函数运行一次就会建立函数闭包。
闭包的实现其实很类似于js对象的实现。函数闭包建立时会将函数内声明的变量登记进一个表中。当函数内存取值时就会查阅此表,表中没有相关变量时就会去父类的闭包中寻找,直至最上层闭包,即最外层所在的闭包。
- JScript code
var value=1;function test(){ var value=7;function inline(){var value=4;alert(value);}inline();}test();//输出4上面总共有三个闭包。一个全局闭包,该闭包中仅登记了一个变量value。test实例一个闭包,该闭包中也登记了一个value变量。inline实例一个闭包,该闭包同样也是只登记了一个value变量。三个闭包间的关系:全局闭包是test实例闭包的父闭包,test实例闭包是inline实例闭包的父闭包。所以输出4。
稍加修改
- JScript code
var value=1;function test(){ function inline(){ alert(value);}}test();//输出1以上面的说明同样是可以解释的。上面的说明同样可以解释js函数中的一个规定。当在函数内不用var声明变量时,该变量被认为是全局变量。因为不使用var,函数内部先在自己的闭包内寻找变量,直至最上层闭包也没有寻找到,故在最上层(全局)声明该变量。
闭包的生存周期:当前闭包内没有任何值被应用,该闭包即销毁。
- JScript code
var getFunc;function test(){ var func= function (){ alert(‘new function ’); } getFunc=function (){ return func;}}test();var func1=getFunc();var func2=getFunc();alert(func1==func2)//输出true;上例中运行test,为test函数实例建立闭包。并对全局变量getFunc赋值。因为getFunc中含有对test实例函数闭包func的引用,所以该闭包不会被销毁,所以返回的总是同一个函数func的引用。还有一个更为典型的例子:
- JScript code
var checkre;function myFunc(){ if(checker){ checker();}alert(‘myFunc:’+str);var str=’ test’;if(!checker){checker=function (){ alert(‘checker:’+str);}}return arguemnts.callee;//返回当前运行函数的引用}myFunc()();//myFunc连续运行两次。结果是
myFunc :undefined
checker: test
myFunc:undefined
上面提到函数每()运行一次,就会建立一个函数闭包。故上例总共为myFunc先后建立了两个函数闭包。第一个函数运行结束后,输出结果第一行,checker被赋值,str登记在此闭包中,因为checker引用str,故第一个函数闭包不会销毁。当函数第二次运行时,checker有值,故运行,但是checker内引用的是第一个闭包内的str=‘test’,故会输出第二行的内容。然后myFunc输出结果第三行,因为此时str引用的当前闭包内的str,故为undefined。
最上面的getFunction的例子。每次都返回一个函数实例,是因为每次都建立一个闭包。
运行时存在函数闭包链,提供对函数外定义的变量的访问。
第一次写,有点散,希望对大家有帮助。
[解决办法]
对于闭包,将 function 译为“功能”比译为“函数”要更贴切些
[解决办法]
学习了,
一直觉得这个不好理解,
适合多次琢磨
------解决方案--------------------
看的似懂非懂的。。闭包要是详细解释下就好了 我在看几遍
[解决办法]
学习了!谢谢
[解决办法]
看了有些似懂非懂,不过至少清晰了些~
[解决办法]
不错的说
[解决办法]
看了有些似懂非懂,不过至少清晰了些~
[解决办法]
看了有些似懂非懂,不过至少清晰了些~
[解决办法]
学习了,留个记号,以备用
[解决办法]
这个需要好好琢磨
[解决办法]
JS 闭包随笔
[解决办法]
[解决办法]
[解决办法]
貌似理解了一点。。
zz一下,以后仔细研究。
[解决办法]
留名 回家仔细研究
[解决办法]
闭包绝对是好东西
[解决办法]
果然是一个好东西,楼主厉害。
[解决办法]
讲的还算不错...
[解决办法]
留个记号,回头看
[解决办法]
楼主写的很好。但是有些小错误呵呵,更正如下:
从上往下的第四个代码段漏了 inline();
=======
var value=1;
function test(){
function inline(){
alert(value);
}
inline();
}
test();//输出1
============
注意红色部分。
最后一个代码段。
===========
return arguemnts.callee;
===========
应该是
return arguments.callee;
谢谢lz,让我清晰不少呵呵~~~
[解决办法]
正在学习闭包这块。。。
[解决办法]
[解决办法]
讲得很好。其中少数代码有笔误,更正如下:
- HTML code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>New Web Project</title> </head> <body> <script type="text/javascript"> var checker; function myFunc(){ if (checker) { checker(); } alert('myFunc:' + str); var str = ' test'; if (!checker) { checker = function(){ alert('checker:' + str); } } return arguments.callee;//返回当前运行函数的引用 } myFunc()();//myFunc连续运行两次。 </script> </body></html>
------解决方案--------------------
弄明白了 this,那闭包也会逐渐开朗!
[解决办法]
[解决办法]
[解决办法]
[解决办法]
[解决办法]
[解决办法]
[解决办法]
[解决办法]
没有看出什么特殊的东西呀
[解决办法]
[解决办法]
谢谢分享!!
[解决办法]