Javascript闭包演示

有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。

<!DOCTYPE HTML>
<html>
<head>
<meta
charset="utf-8" />
<title>闭包演示</title>
<style
type="text/css">
p {background:gold;}
</style>
<script
type="text/javascript">
function init() {
var pAry =
document.getElementsByTagName("p");
for( var i=0; i<pAry.length;
i++ ) {
pAry[i].onclick = function() {
alert(i);

}
}
}
</script>
</head>
<body
>
<p>产品 0</p>
<p>产品 1</p>

<p>产品 2</p>
<p>产品 3</p>
<p>产品
4</p>
</body>
</html>
  

以上场景是初学者经常碰到的。即获取HTML元素集合,循环给元素添加事件。在事件响应函数中(event
handler)获取对应的索引。但每次获取的都是最后一次循环的索引。

原因是初学者并未理解JavaScript的闭包特性。通过element.onclick=function(){alert(i);}方式给元素添加点击事件。响应函数function(){alert(i);}中的
i 并非每次循环时对应的 i(如0,1,2,3,4)而是循环后最后 i 的值5。 或者说循环时响应函数内并未能保存对应的值
i,而是最后一次i++的值5。

了解了原因,摸索出了很多解决办法(纯粹是兴趣)。最先想到的前两种

1、将变量 i 保存给在每个段落对象(p)上

function init1() {
var pAry = document.getElementsByTagName("p");

for( var i=0; i<pAry.length; i++ ) {
pAry[i].i = i;

pAry[i].onclick = function() {
alert(this.i);
}

}
}

2、将变量 i 保存在匿名函数自身

function init2() {
var pAry = document.getElementsByTagName("p");

for( var i=0; i<pAry.length; i++ ) {
(pAry[i].onclick = function()
{
alert(arguments.callee.i);
}).i = i;
}
}

后又想到了三种

3、加一层闭包,i 以函数参数形式传递给内层函数

function init3() {
var pAry = document.getElementsByTagName("p");

for( var i=0; i<pAry.length; i++ ) {
(function(arg){

pAry[i].onclick = function() {
alert(arg);
};

})(i);//调用时参数
}
}

4、加一层闭包,i 以局部变量形式传递给内层函数

function init4() {
var pAry =
document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ ) {

(function () {
var temp = i;//调用时局部变量
pAry[i].onclick =
function() {
alert(temp);
}
})();

}
}
  

5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

function init5() {
var pAry = document.getElementsByTagName("p");

for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick = function(arg)
{
return function() {//返回一个函数
alert(arg);
}

}(i);
}
}

后又发现了两种

6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
function init6() {
var pAry =
document.getElementsByTagName("p");
for( var i=0; i<pAry.length; i++ )
{
pAry[i].onclick = new Function("alert(" + i +
");");//new一次就产生一个函数实例
}
}
  

7、用Function实现,注意与6的区别

function init7() {
var pAry = document.getElementsByTagName("p");

for( var i=0; i<pAry.length; i++ ) {
pAry[i].onclick =
Function(‘alert(‘+i+‘)‘);
}
}

Javascript闭包演示,布布扣,bubuko.com

时间: 2024-10-22 06:51:32

Javascript闭包演示的相关文章

Javascript闭包演示【转】

文章出自http://www.cnblogs.com/snandy/archive/2011/03/01/1967628.html 有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 <!DOCTYPE HTML> <html> <head> <meta ch

js闭包演示

有个网友问了个问题,如下的html,为什么每次输出都是5 <html > <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>闭包演示</title> <style type="text/css"> </style> <script type=

JavaScript闭包模型

  JavaScript闭包模型 -----  [原创翻译]2016-09-01  09:32:22 < 一>  闭包并不神秘 本文利用JavaScript代码来阐述闭包,目的是为了使普通开发者能很好的理解闭包,并不面向专家或函数式编程开发者. 一旦领悟了闭包的核心思想,它就不再难于理解:然而,只看一些理论上的文档或是以理论为中心的文档只会让你南辕北辙. 本文适用于那些在主流编程语言中有一定编程经历的开发者们,且能看懂如下的JavaScript函数: 1 function sayHello(n

深入理解javascript闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现. 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量. Js代码 var n=999; function f1(){ alert(n); } f1(); // 999 另一方面,在函数外部自然无法读取函数内的局部变量. Js代码 function

JavaScript 闭包

1.词法作用域: 简单地说子集能访问父级的变量, 说人话就是变量拿来就用不用传入 2.函数局部变量: 在函数体中以var 声明变量的为局部变量 + 函数传入的参数, 直接写变量名声明的变量是全局变量 3.局部变量生存期: 局部变量在函数函数的执行期间可用,  一旦执行过后,局部变量将不再可用 4.延长局部变量生存期: 现在问题来了,我想要延长局部变量的生存期,怎么办.(因为调用函数不仅仅是为了return, 有时候还需要保存函数中的状态, 或者实现类等等) 5.使用全局变量不好吗: 不好.有时函

javascript—闭包

javascript 闭包就是在另一个作用域中保存了一份它从上一级函数或作用域取得的变量(键值对0), 而这些键值对是不会随上一级函数的执行完成而销毁. function a(){ var i=0; function b(){ alert(++i); } return b; } var c=a(); c(); 在执行完var c=a()后,变量c实际上是指向了函数b,b中用到了变量i, 再执行c()后就会弹出一个窗口显示i的值(第一次为1).这段代码其实就创建了一个闭包. 为什么?因为函数a外的

JavaScript 闭包究竟是什么

JavaScript 闭包究竟是什么 1.简单的例子 首先从一个经典错误谈起,页面上有若干个div, 我们想给它们绑定一个onclick方法,于是有了下面的代码 <div id="divTest"> <span>0</span> <span>1</span> <span>2</span> <span>3</span> </div> <div id="d

全面理解Javascript闭包和闭包的几种写法及用途

一.什么是闭包和闭包的几种写法和用法                                                       1.什么是闭包 闭包,官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分.闭包的特点: 1. 作为一个函数变量的一个引用,当函数返回时,其处于激活状态. 2. 一个闭包就是当一个函数返回时,一个没有释放资源的栈区. 简单的说,Javascript允许使用内部函数---即函数定义和函数表

javascript闭包的简单理解

奖Javascript闭包前,先给大家讲个小故事 故事背景:刘备和曹操煮酒的时间段,故事可能有点小差异,刘备为曹操手下,关羽为间谍. 咳咳 曹操很想知道手下新来的刘备整天鼓捣啥: 曹操就问刘备,玄德你整天鼓捣啥: 刘备想,我靠这怎么能告诉你,劳资岂不是找死,打个马虎眼就过去了,曹操什么也没问出来: 刘备回到家里,跟关羽说,二弟,哼,曹操那个傻吊,哼! 关羽晚上也回到家里,跟老婆说,哼,大哥那个傻吊,哼!我这就去告诉丞相: 曹操也不能罢休,就去问关羽,关羽正要去告密,就一五一十  ¥%…@?%%: