JavaScript学习笔记之闭包

来源:互联网 发布:淘宝信用最高的店铺 编辑:程序博客网 时间:2024/06/05 03:28

JavaScript中,由于变量的作用域和生命周期限制,使得局部变量只能在作用域内有效,闭包的出现,使得局部变量的作用域扩大。

函数调用完成之后,其执行上下文环境不会接着被销毁,这便是闭包的核心内容。闭包实现的关键在于:函数作为返回值,函数作为参数传递。


在学习闭包的时候,看到一段代码,实现一个基础计数器的功能。虽然简单,但是这段代码,让我对JavaScript有了更深层次的理解:

<body><p>局部变量计数。</p><button type="button" onclick="myFunction()">计数!</button><p id="demo">0</p><script>var add = (function () {    var counter = 0;    return function () {return counter += 1;}})();function myFunction(){    document.getElementById("demo").innerHTML = add();}</script></body>
代码示例来自:http://www.runoob.com/try/try.php?filename=tryjs_function_counter3

1.对于“()”:圆括号"()"在JavaScript中,表示立即执行方法/函数,如果没有"()",可以将方法/函数看做一段普通的字符串,有了"()",浏览器(JavaScript解析器)才开始解析这个字符串,把它当做JavaScript方法来执行,也就是调用方法/函数。

2.对于整段代码的执行:

“document.getElementById("demo").innerHTML = add()”中的add(),可以分为两部分来看,“add”和“()”。

(1):“add”部分:

var add = (function () {    var counter = 0;    return function () {return counter += 1;}})();
最末尾的“()”表示需要执行前面括号中的代码,也就是“function () { var counter = 0; return function () {return counter += 1;}}”,该段代码执行完成,返回的是“function () {return counter += 1;}”。这是一个函数。如果没有地方调用这个函数,那么它也就差不多是一个普通的字符串。那么就涉及到下面说的“add()”后面的圆括号的作用。

(2):“()”部分:表示调用add返回的函数,也就是“function () {return counter += 1;}”。

计数器受匿名函数的作用域保护,只能通过 add 方法修改。闭包使得函数拥有私有变量变成可能。



下面的这段代码,是对作用域以及变量的取值问题有了更清晰的理解:

var x =10;function fn(){console.log(x);}function show(f){var x=20;(function (){f();})();}show(fn);//结果是10而不是20
对于X的取值:要到创建这个函数的那个作用域中取值——是“创建”,而不是“调用”。

刚开始的时候粗略看代码,觉得"f()",这个函数是什么函数,没有定义,难道不会报错??自己去试了这段代码才发现,show(fn)中,传递的参数是fn,在"function show(f){}"中,fn作为参数传递给show,并且show方法中的匿名函数中,f()是来自show方法的参数,所以这里也是闭包中的“函数作为参数传递”这一实现方式。


请参考更详细的关于闭包的介绍:http://www.cnblogs.com/wangfupeng1988/p/3994065.html