第一次代码
<body>
<p class="p_area" id="1">1</p>
<p class="p_area" id="2">2</p>
<p class="p_area" id="3">3</p>
<p class="p_area" id="4">4</p>
<p class="p_area" id="5">5</p>
<script>
var p=document.getElementsByClassName("p_area");
for(var i=0;i<p.length;i++){
p[i].onclick=function(){
alert(p[i].id);
}
}
</script>
</body>
这段代码无法实现点击p输出p的id,因为i的值时5,但是我不明白的是为什么i的值是5,这是因为js没有块级作用域导致的还是闭包(看起来不是闭包啊,闭包最常见创建方式的不是函数内嵌函数吗,这里只有一个函数啊)
于是我把代码修改了以后为什么就又可以了?
第二次代码:
alert(this.id);
接着我又把js代码改成了这样,创造了一个闭包,结果i的值也是5,所以DOM找不到,我想问造成i=5的原因和第一次的时候是否时一样的?
第三次代码:
<script>
var p=document.getElementsByClassName("p_area");
function add(){
for(var i=0;i<p.length;i++){
p[i].onclick=function(){
alert(p[i].id);
}
}
}
add();
</script>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
本质上是一样的。
在执行
alert(p[i].id);的时候,for循环已经完成,i的值已经变成5了。而this绑定的始终是被点击的对象。SegmentFault 上已经出现若干关于类似的装闭包问题了。
闭包一定要注意变量的作用域,因为你的闭包中一直都是用的同一个变量 i,而 i 是变化的,所以最好到使用的时候都是 i 的终值。
其实可以不用闭包,因为在 onclick 函数里直接用
this就是绑定事件的那个 p 啊。因为你onclick执行的时候,循环肯定早就执行完了,这时i为5。你可以试试改成立即执行的函数,是不是感觉正常了?
少年郎...建议你先去看《JavaScript 高级程序设计》第七章...你就懂啥是闭包了...
没有书也没关系...可以看别人归纳的读书笔记...比如我的~= ̄ω ̄=~
然后做一做常见的面试题...比如这篇
关于 this 指针的指向问题推荐看看《JavaScript秘密花园》
这个就是闭包。
闭包不一定必须是两个函数嵌套,而是两个词法环境嵌套。只不过函数是最常见的可以形成词法环境的词法结构。
除了函数外,全局上下文、with语句、catch子句都可以形成词法结构,从而构成闭包。
这个我来说说吧。
①因为你在for循环中。i 始终都是一个变量。在开始注册事件的时候,每个p对象的onclick属性都是一个函数,并且这个函数是
,没错,这里是p[i].id,i的值还不确定。这里还没执行的。执行的条件就是你在浏览器点击了p,这时在内部循环已经完成该了。i=5。
②每个onclick事件执行时,this会绑定到点击它的dom元素。更详细的解释:每个p都是一个对象,onclick是它的属性,类似
,所以这个this隐式绑定到p[i]上。点击的时候会找到这个p的id属性。你可以把id的值换了试一试。
③和1是一样的。并不是闭包。闭包的概念:是在当前的作用域能使用其他作用域。这里可以使用一个即时函数(IIFE)。
如果还有什么不明白可以追问喔。答得不好的请多多包涵:)
----二次更新
一和三都不是闭包(个人看法)。如下代码
以上就是闭包。
解释如下:函数bar()的词法作用域能够访问foo()的内部作用域。然后将bar函数本身当作一个值类型进行传递。bar显然可以正常执行,在这个例子中,它在自己定义的词法作用域以外的地方执行。
在foo()执行后,通常会期待foo()的整个内部作用域被销毁(js的垃圾回收器)。
而闭包的"神奇"之处是可以阻止这件事情的发生。因为在bar()声明的地方,它拥有涵盖foo()内部作用域的闭包,使得该作用域能够一直存在,以供bar()在之后任何时间进行引用。
bar()依然持有对该作用域的引用,而这个引用就是闭包。
-----------------------------以下为书中原话(译版)
上面是书中原话。最后一段解释我感觉很模棱两可。可能是翻译的原因或者我没理解。
书名:你不知道的JavaScript上卷 没找到英文版,哪位找到发我一份啊。。谢谢啦!