这里有新鲜出炉的 Javascript 教程,程序狗速度看过来!
Javascript 是一种由 Netscape 的 LiveScript 发展而来的原型化继承的基于对象的动态类型的区分大小写的客户端脚本语言,主要目的是为了解决服务器端语言,比如 Perl,遗留的速度问题,为客户提供更流畅的浏览效果。
这篇文章主要介绍了 JavaScript 闭包函数访问外部变量的方法, 本文使用匿名函数来实现在闭包中访问外部变量, 需要的朋友可以参考下
闭包是指有权访问另一个函数作用域中的变量的函数,但作用域的配置机制有一个需要注意的地方,即闭包只能取得包含函数中任何变量的最后一个值。
如以下案例:
- function create(){
- var arr = new Array();
- for (var i=0; i<10; i++){
- arr[i] = function(){
- return i;
- };
- }
- return arr;
- }
- var c_arr = create();
- for(var i=0; i<c_arr.length;i++){
- document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />");
- }
执行结果:
表面上看,似乎每个函数返回的 i 值都不相同,比如 c_arr[0] 的值应该是 0,c_arr[1] 的值应该是 1,以此类推。可结果每个函数都返回 10。为什么呢?
因为每个函数的作用域链中保存着 create() 函数的活动对象,所以它们引用的都是同一个变量 i。当 for 循环结束以后,i 的值也就变成 10 了,此时每个函数都引用保存变量 i 的同一个变量对象。
我们可以通过创建另一个域名函数强制让闭包的行为符合预期,使每个位置对应相应的值。
- function create(){
- var arr = new Array();
- for (var i=0; i<10; i++){
- arr[i] = function(num){
- return function(){
- return num;
- };
- }(i);
- }
- return arr;
- }
- var c_arr = create();
- for(var i=0; i<c_arr.length;i++){
- document.write("c_arr["+i+"] = "+c_arr[i]()+"<br />");
- }
执行结果:
定义了一个匿名函数,并立即执行匿名函数的机过赋给数组,这里匿名函数有一个参数 num,也就是最终的函数要返回的值。在调用每个函数时我们传入变量 i。由于函数参数是按值传递的,所以就会将变量 i 的当前值赋值给参数 num。而在这个匿名函数内部,又创建并返回了一个访问 num 的闭包,这样一来 arr 数组中的每个函数都有自己 num 变量的一个副本,因此就可以返回各自不同的数值了。
经典例子
我们再来看一个经典的例子,假设页面有一组 button 标签,我们利用脚本给这组 button 标签绑定单击事件,并且单击时能弹出这是第几个标签。
- <meta charset="utf-8" />
- <button>
- 第一个
- </button>
- <button>
- 第二个
- </button>
- <button>
- 第三个
- </button>
- <button>
- 第四个
- </button>
- <script type="text/javascript">
- var obj = document.getElementsByTagName('button');
- for (var i = 0; i < obj.length; i++) { obj[i].onclick = function() { alert(i);
- };
- }
- </script>
点击每一个按钮结果
表面上看,似乎单击每一个标签应该弹出不同数字
第一个应该弹出 0;
第二个应该弹出 1;
以此类推。
可结果是所有按钮都弹出 4,显然这不是我们想要的结果。
我们把程序改一下
- <meta charset="utf-8" />
- <button>
- 第一个
- </button>
- <button>
- 第二个
- </button>
- <button>
- 第三个
- </button>
- <button>
- 第四个
- </button>
- <script type="text/javascript">
- var obj = document.getElementsByTagName('button');
- for (var i = 0; i < obj.length; i++) { obj[i].onclick = function(num) {
- return function() { alert(num);
- }
- } (i);
- }
- </script>
点击第二个
点击第四个
我们只需要在函数内建立一个匿名函数,同以上案例同理。即可实现匿名函数捕获外部变量 i,结果每个按钮弹的 i 值都不同。
来源: http://www.phperz.com/article/17/0415/275003.html