JavaScript闭包示例
在下面的例子中,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。
<html>
<head>
<meta charset="utf-8" />
<title>闭包演示</title>
<style type="text/css">
p {background:#ccc;}
</style>
<script type="text/javascript">
window.onload = function() {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
arr[i].onclick = function() {
alert(i);
}
}
}
</script>
</head>
<body>
<p>000</p>
<p>111</p>
<p>222</p>
<p>333</p>
<p>444</p>
</body>
</html>
原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元素添加 点击事件。响应函数function(){alert(i);}中的 i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值 i,而是最后一次i++的值5。
方法1:将变量 i 保存给在每个段落对象(p)上
window.onload = function(){
var arr = document.getElementsByTagName('p');
for(var i=0; i<arr.length; i++){
arr[i].i= i; //或 arr[i].index = i;
arr[i].onclick = function(){
alert(this.i); //或alert(this.index);
}
}
}
方法2:加一层闭包,i 以函数参数形式传递给内层函数
window.onload = function () {
var arr= document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {
(function(arg){
arr[i].onclick = function() {
alert(arg);
};
})(i);//调用时参数
}
}
方法3:将变量 i 保存在匿名函数自身
window.onload = function () {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
(arr[i].onclick = function() {
alert(arguments.callee.i);
}).i = i;
}
}
4、加一层闭包,i 以局部变量形式传递给内层函数
1 window.onload = function () {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
(function () {
var temp = i;//调用时局部变量
arr[i].onclick = function() {
alert(temp);
}
})();
}
}
5、加一层闭包,返回一个函数作为响应事件(注意与2的细微区别)
window.onload = function () {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
arr[i].onclick = function(arg) {
return function() {//返回一个函数
alert(arg);
}
}(i);
}
}
6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
window.onload = function() {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
arr[i].onclick = new Function("alert(" + i + ");"); //new一次就产生一个函数实例
}
}
7、用Function实现,注意与6的区别
window.onload = function() {
var arr= document.getElementsByTagName("p");
for( var i=0; i<arr.length; i++ ) {
arr[i].onclick = Function('alert('+i+')');
}
}
JavaScript闭包示例的更多相关文章
- 一个简单的Javascript闭包示例
//=====用闭包实现函数的Curry化===== //数字求和函数的函数生成器 function addGenerator( num ){ //返回一个简单的匿名函数,求两个数的和,其中第一个数字 ...
- JavaScript 闭包(个人理解)
当function里嵌套function时,内部的function可以访问外部function里的变量.但这不是闭包 function foo(x) { var tmp = 3; function b ...
- 通过示例学习JavaScript闭包
译者按: 在上一篇博客,我们通过实现一个计数器,了解了如何使用闭包(Closure),这篇博客将提供一些代码示例,帮助大家理解闭包. 原文: JavaScript Closures for Dummi ...
- [JavaScript闭包]Javascript闭包的判别,作用和示例
闭包是JavaScript最重要的特性之一,也是全栈/前端/JS面试的考点. 那闭包究竟该如何理解呢? 如果不爱看文字,喜欢看视频.那本文配套讲解视频已发送到B站上供大家参考学习. 如果觉得有所收获, ...
- JavaScript学习总结——我所理解的JavaScript闭包
一.闭包(Closure) 1.1.什么是闭包? 理解闭包概念: a.闭包是指有权限访问另一个函数作用域的变量的函数,创建闭包的常见方式就是在一个函数内部创建另一个函数,也就是创建一个内部函数,创建一 ...
- Javascript闭包和C#匿名函数对比分析
C#中引入匿名函数,多少都是受到Javascript的闭包语法和面向函数编程语言的影响.人们发现,在表达式中直接编写函数代码是一种普遍存在的需求,这种语法将比那种必须在某个特定地方定义函数的方式灵活和 ...
- javascript 闭包最简单理解
首先说3点与闭包有关系的东西. 一.变量的作用域 变量的作用域不难理解. 1.函数内部可以访问函数外部的变量,而函数外部不能访问函数内部的变量. 2.如果在函数内定义变量的时候,不加var,那么是全局 ...
- JavaScript闭包(一)——实现
闭包的官方的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分. 通俗点的说法是: 从理论角度:所有的函数.因为它们都在创建的时候就将上层上下文 ...
- 我所理解的JavaScript闭包
目录 一.闭包(Closure) 1.1.什么是闭包? 1.2.为什么要用闭包(作用)? 1.2.1.保护函数内的变量安全. 1.2.2.通过访问外部变量,一个闭包可以暂时保存这些变量的上下文环境,当 ...
随机推荐
- ffmpeg 错误码
av_read_frame, av_write_frame等 经常会返回负值也即写数据包失败.不同的负值代表不同的含义,可以根据错误码定义,定位问题. #define EPERM 1 /* Opera ...
- [resource]23个python的机器学习包
23个python的机器学习包,从常见的scikit-learn, pylearn2,经典的matlab替代orange, 到最新最酷的Theano(深度学习)和torch 7 (well,其实lua ...
- Maven搭建webService (二) 创建服务端---使用web方式发布服务
今天和大家分享 使用 web方式发布 webService 服务端.客户端 1.首先创建 一个web工程(增加Maven依赖) 2.增加Maven依赖包,如下: <!-- spring core ...
- SQL SERVER 之 填充因子
填充因子依附索引而存在,但创建索引,就意味着要对表进行DML时,必须处理额外的工作量(也就是对索引结构的维护)以及存储方面的IO开销. 所以创建索引时,需要考虑创建索引所带来的查询性能方面的提高,与引 ...
- hlsl 和cg 涉及 mul 左乘 右乘
error: 1. mul' implicit truncation of vector type 2. matrixXXX: array dimensions of(unknown scope en ...
- select模式
在很多比较各种网络模型的文章中,但凡提到select模型时,都会说select受限于轮询的套接字数量,这个 数量也就是系统头文件中定义的FD_SETSIZE值(例如64).但事实上这个算不上真的限制. ...
- zend studio 10 字体,颜色,快捷键等相关设置
一.修改字体 没想到zend studio 10中对中文显示不太好看,似乎有点小了.修改如下:打开 Window->Preferences->General->Appearance- ...
- Using command-line Subversion to access project source files
Help index About source code version control with Software Configuration Management (Subversion) Usi ...
- Interface Comparator
int compare(T o1, T o2) Compares its two arguments for order. Returns a negative integer, zero, or a ...
- C#接口的经典案例
C#接口(interface)实例子(简单而经典)2008/12/04 10:04using System; using System.Collections.Generic; using Syste ...