有个网友问了个问题,如下的html,为什么点击所有的段落p输出都是5,而不是alert出对应的0,1,2,3,4。
04
|
<
meta
charset
=
"utf-8"
/>
|
05
|
<
title
>闭包演示</
title
>
|
06
|
<
style
type
=
"text/css"
>
|
09
|
<
script
type
=
"text/javascript"
>
|
11
|
var pAry = document.getElementsByTagName("p");
|
12
|
for( var i=0; i<
pAry.length
; i++ ) {
|
13
|
pAry[i]
.onclick
=
function
() {
|
20
|
<
body
onload
=
"init();"
>
|
以上场景是初学者经常碰到的。即获取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)上
2
|
var
pAry = document.getElementsByTagName(
"p"
);
|
3
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
5
|
pAry[i].onclick =
function
() {
|
2、将变量 i 保存在匿名函数自身
2
|
var
pAry = document.getElementsByTagName(
"p"
);
|
3
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
4
|
(pAry[i].onclick =
function
() {
|
5
|
alert(arguments.callee.i);
|
后又想到了三种
3、加一层闭包,i 以函数参数形式传递给内层函数
02
|
var
pAry = document.getElementsByTagName(
"p"
);
|
03
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
05
|
pAry[i].onclick =
function
() {
|
4、加一层闭包,i 以局部变量形式传递给内层函数
02
|
var
pAry = document.getElementsByTagName(
"p"
);
|
03
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
06
|
pAry[i].onclick =
function
() {
|
5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)
02
|
var
pAry = document.getElementsByTagName(
"p"
);
|
03
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
04
|
pAry[i].onclick =
function
(arg) {
|
后又发现了两种
6、用Function实现,实际上每产生一个函数实例就会产生一个闭包
2
|
var
pAry = document.getElementsByTagName(
"p"
);
|
3
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
4
|
pAry[i].onclick =
new
Function(
"alert("
+ i +
");"
);
|
7、用Function实现,注意与6的区别
2
|
var
pAry = document.getElementsByTagName(
"p"
);
|
3
|
for
(
var
i=0; i<pAry.length; i++ ) {
|
4
|
pAry[i].onclick = Function(
'alert('
+i+
')'
);
|
分享到:
相关推荐
闭包演示 p {background:gold;} function init() { var pAry = document.getElementsByTagName(“p”); for( var i=0; i 产品 0 产品 1 产品 2 产品 3 产品 4 [Ctrl+A 全选 注:如需引入外部Js需刷新才能执行]...
JavaScript 闭包是一种高级编程概念,它在JavaScript中扮演着至关重要的角色,特别是在函数式编程和模块化设计中。闭包本质上是函数和其能够访问...通过学习这些实例,你将能够更好地掌握JavaScript闭包这一核心概念。
为了帮助大家快速和较好地理解JavaScript函数中的闭包,本文对JavaScript的闭包进行了分析并进行简易的代码演示,希望本文能够给有需要的人带来一点小小的帮助。
在这个"javascript演示程序"中,我们可以深入理解JavaScript的核心概念和常见应用。 首先,JavaScript的基本语法与C++和Java类似,它包括变量、数据类型(如字符串、数字、布尔值、对象等)、运算符、控制结构(如...
在本资料的"javascript代码和网页演示_PART4"中,可能包含了一些高级话题,如事件处理、AJAX异步通信、闭包、原型链等。事件处理是JavaScript与用户交互的关键,当用户点击按钮、滚动页面等,对应的事件处理器会被...
JavaScript闭包是这门语言的核心概念之一,它允许函数访问外部函数中的局部变量、参数和内部定义的其他函数。闭包的创建通常发生在函数被返回并赋值给一个全局变量时,即使外部函数已经执行完毕,这些变量也不会被...
闭包是JavaScript编程中一个非常重要的概念,它在函数式编程和对象封装中扮演着核心角色。闭包简单来说就是能够记住其词法作用域(定义时的作用域)的函数,即使该函数在外部作用域被调用。这种特性使得闭包在管理...
7. **闭包**:JavaScript的闭包特性可以用来管理作用域,保护内部变量不被外部访问,同时在动画执行过程中保持状态。 8. **性能优化**:对于大规模的病毒元素,可能需要考虑性能优化,比如使用...
例子将演示如何处理回调函数、Promise链式调用以及异步操作的错误处理。 7. **JavaScript模板字符串**:模板字符串是ES6引入的新特性,允许在字符串中嵌入表达式。例子可能包含使用模板字符串构建动态HTML内容的...
这个存储库包含JavaScript Closure演示。 在我们开始讨论闭包之前,重要的是我们理解以下术语,因为它们将构成我们对闭包的整个理解的基线: 1. 词法范围 词法是指语言或文本。 范围是指与文本相关的属性。 词法...
这个"带演示的常用Javascript特效代码集"包含了多种常见的JavaScript特效实现,对于开发者来说是一份宝贵的参考资料。以下是对其中可能包含的知识点的详细说明: 1. **DOM操作**:在JavaScript中,DOM(Document ...
最后,"JavaScript.ppt"可能是JavaScript的演示文稿,包含了语言的主要知识点和实例,可能涵盖从基础到进阶的主题,如闭包、异步编程、AJAX(异步JavaScript和XML)以及ES6的新特性,如箭头函数、模板字符串、...
通常,开发者会编写测试用例来演示闭包如何工作,例如,如何使用闭包来保存状态、创建私有变量或者实现异步操作的回调函数等。 在标签中,“源码”意味着我们将探讨闭包在实际代码中的应用,理解其底层工作原理。而...
有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p...闭包演示</title> [removed] function init() { var pAry = document.getElementsByTagName(p); for( var i=0; i<pAry.length; i
书中详细阐述了这些基础知识,并通过实例演示如何在实际编程中应用它们。 其次,JavaScript的面向对象特性是其重要组成部分。书中会讲解如何使用构造函数、原型链以及闭包来实现面向对象编程。此外,ES6引入的类和...
–这就是闭包的问题 原来 在js中,函数中在定义函数,就出现闭包了。此时外层函数中变量是可以在里层函数里利用的,即使外层函数结束。但是当外层中出现循环的时候,如果在里层函数中利用这个循环变量的话,会直接...