JavaScript闭包函数访问外部变量的方法


Posted in Javascript onAugust 27, 2014

闭包是指有权访问另一个函数作用域中的变量的函数,但作用域的配置机制有一个需要注意的地方,即闭包只能取得包含函数中任何变量的最后一个值。

如以下案例:

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 />");    
}

执行结果:

JavaScript闭包函数访问外部变量的方法

表面上看,似乎每个函数返回的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 />");    
}

执行结果:

JavaScript闭包函数访问外部变量的方法

定义了一个匿名函数,并立即执行匿名函数的机过赋给数组,这里匿名函数有一个参数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>

点击每一个按钮结果

JavaScript闭包函数访问外部变量的方法

表面上看,似乎单击每一个标签应该弹出不同数字

第一个应该弹出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>

点击第二个

JavaScript闭包函数访问外部变量的方法

点击第四个

JavaScript闭包函数访问外部变量的方法

我们只需要在函数内建立一个匿名函数,同以上案例同理。即可实现匿名函数捕获外部变量i,结果每个按钮弹的i值都不同。

Javascript 相关文章推荐
jQuery方法简洁实现隔行换色及toggleClass的使用
Mar 15 Javascript
让alert不出现弹窗的两种方法
May 18 Javascript
node.js中的fs.renameSync方法使用说明
Dec 16 Javascript
jQuery中extend函数的实现原理详解
Feb 03 Javascript
javascript框架设计之框架分类及主要功能
Jun 23 Javascript
实例详解JavaScript获取链接参数的方法
Jan 01 Javascript
JQuery validate 验证一个单独的表单元素实例
Feb 17 Javascript
网页中右键功能的实现方法之contextMenu的使用
Feb 20 Javascript
node.js 核心http模块,起一个服务器,返回一个页面的实例
Sep 11 Javascript
vue toggle做一个点击切换class(实例讲解)
Mar 13 Javascript
DatePickerDialog 自定义样式及使用全解
Jul 09 Javascript
Vue监听滚动实现锚点定位(双向)示例
Nov 13 Javascript
JavaScript中switch判断容易犯错的一个细节
Aug 27 #Javascript
JavaScript中使用arguments获得函数传参个数实例
Aug 27 #Javascript
JavaScript中输出标签的方法
Aug 27 #Javascript
JavaScript实现的GBK、UTF8字符串实际长度计算函数
Aug 27 #Javascript
JavaScript实现的使用键盘控制人物走动实例
Aug 27 #Javascript
JavaScript截取字符串的2个函数介绍
Aug 27 #Javascript
JavaScript中判断页面关闭、页面刷新的实现代码
Aug 27 #Javascript
You might like
PHP insert语法详解
2008/06/07 PHP
PHP执行linux系统命令的常用函数使用说明
2010/04/27 PHP
解析phpstorm + xdebug 远程断点调试
2013/06/20 PHP
免费手机号码归属地API查询接口和PHP使用实例分享
2014/04/10 PHP
PHP swoole和redis异步任务实现方法分析
2019/08/12 PHP
php设计模式之状态模式实例分析【星际争霸游戏案例】
2020/03/26 PHP
广告切换效果(缓动切换)
2009/05/27 Javascript
Mootools 1.2教程 定时器和哈希简介
2009/09/15 Javascript
用jQuery模拟页面加载进度条的实现代码
2011/12/19 Javascript
Js如何判断客户端是PC还是手持设备简单分析
2012/11/22 Javascript
js仿百度贴吧验证码特效实例代码
2014/01/16 Javascript
7个JS基础知识总结
2014/03/05 Javascript
JavaScript版经典游戏之扫雷游戏完整示例【附demo源码下载】
2016/12/12 Javascript
JavaScript requestAnimationFrame动画详解
2017/09/14 Javascript
Angular如何在应用初始化时运行代码详解
2018/06/11 Javascript
详解在React-Native中持久化redux数据
2019/05/22 Javascript
vue 接口请求地址前缀本地开发和线上开发设置方式
2020/08/13 Javascript
javascript canvas封装动态时钟
2020/09/30 Javascript
使用python统计文件行数示例分享
2014/02/21 Python
深入解析Python中的lambda表达式的用法
2015/08/28 Python
使用Mixin设计模式进行Python编程的方法讲解
2016/06/21 Python
利用Python爬取微博数据生成词云图片实例代码
2017/08/31 Python
利用selenium 3.7和python3添加cookie模拟登陆的实现
2017/11/20 Python
Python编程学习之如何判断3个数的大小
2019/08/07 Python
python创建n行m列数组示例
2019/12/02 Python
python标识符命名规范原理解析
2020/01/10 Python
pytorch实现MNIST手写体识别
2020/02/14 Python
Django中ORM的基本使用教程
2020/12/22 Python
CSS3中的元素过渡属性transition示例详解
2016/11/30 HTML / CSS
HTML5 Canvas API中drawImage()方法的使用实例
2016/03/25 HTML / CSS
请用Java实现列出某个目录下的所有文件
2013/09/23 面试题
如何理解transaction事务的概念
2015/05/27 面试题
监察建议书范文
2014/03/12 职场文书
会计与审计专业自荐信范文
2014/03/15 职场文书
团日活动总结格式
2015/05/11 职场文书
酒店工程部的岗位职责汇总大全
2019/10/23 职场文书