之前讲闭包的文章,很多初学者,还是没懂,还是在写一篇。原文地址:http://www.w3cfuns.com/blog-5471724-5409375.html
先说句题外话,你看完之后,觉得讲得清楚的话,点个赞,只要两个就能上今日推荐,让更多人看到。如果认为我讲的不好,甚至讲错了,欢迎指正。
本文开始,先看最简单的代码。
function a(){
function b(){
x++;
return x;
}
console.dir(b);
}
a();
我再来说说闭包,保证初学者能看懂
从上面可以看出,b函数中是保存a作用域中的x的,虽然从chrome中可以看出,x保存在b的closure中,
但是我们也不会吧b叫做闭包的。因为此时b不能在a的作用域之外调用从而访问a中的变量x;
我们先看看在a中调用b的情形
function a(){
var x = 0;
function b(){
x++;
return x;
}
b();
b();
console.dir(b);
}
a();
我再来说说闭包,保证初学者能看懂
b中的确实保存了x的最新值。再一次声明,b不能叫做闭包,在我看来就是作用域链的问题。就像你说女人是人,是正确的。如果你把女人当人的定义来说。我就不同意了。
作用域链能解释明白的事情,就没必要发明闭包这个概念。
作用域链是产生闭包这个现象的核心条件之一,还差另一个重要的因素,才是我们说的闭包现象。那就是你这个b函数必须在a的作用域之外调用才行。
怎么能在a的作用域之外调用b呢,两个办法。1.把b做为a的返回值结构的一部分。2.把b绑定dom的事件上。
对于第一种,a能返回b,运行完a之后,保存a的返回结果,自然拿到b函数,然后再调用b,这样确实是在a的作用域之外调用b了。
至于第二种,把b绑定dom的click事件上,我们点击dom触发b运行,也可以说在a的作用域之外,调用了b。
多说一句,js中为啥有闭包现象,函数能当参数传,能当返回值,这才是核心原因,也是js这么屌的原因。
这里主要来说说第一种情况
function a(){
var x = 0;
function b(){
x++;
return x;
}
return b;
}
var c =a();
c();
c();
console.dir(c);
我再来说说闭包,保证初学者能看懂
从打印来看c正是a中的b,c运行两次,相当在a中运行了b两次。
而初学者,之所以容易弄不明白,总觉得运行两次c,认为里面的x仍始终是1;
原因很简单,c()这么调用不是运行a,实际是运行b,而a呢,你始终运行了一次。如代码中var c = a()这句话。
初学者之所以觉得x始终是1,其实像如下代码调用,才是你错误理解的方式
function a(){
var x = 0;
function b(){
x++;
return x;
}
return b;
}
var c =a();
c();
var d =a();
d();
console.dir(c);
console.dir(d);
我再来说说闭包,保证初学者能看懂
c和d其实都是b,注意这里两个b不是同一个b,是长的一模一样的双胞胎,因为a运行了两次,因而是两个。建议你研究研究,值类型和引用类型的区别。
至于绑定dom,自己敲敲代码吧。
c和d其实都是b,注意这里两个b不是同一个b,是长的一模一样的双胞胎,因为a运行了两次,因而是两个。建议你研究研究,值类型和引用类型的区别。
至于绑定dom,自己敲敲代码吧。
本文完。
<script>
var a =function(){
var x =0;
function f(){
alert(++x);
}
f();
f();
try{
return f
}
finally{
f();
f();
}
}
var b =a();//返回里面的f
b();
b();
//用于对比
function g(){
alert(++x);
}
console.dir(b);
console.dir(g);
</script>
我也来说说闭包,续例
finally可以忽略,只是演示一下,返回完以后运行的情况。其他不多说了,此时无声胜有声。在来一个绑定到dom上闭包情形
<section>
<button id="btn1">按钮1</button>
<button id="btn2">按钮2</button>
</section>
<script>
var c = function(){
var x =3;
var b1=document.getElementById('btn1');
b1.onclick = function(){alert(x)};
console.dir(b1.onclick);
}
c();
var d = function(){
var x =3;
var b2=document.getElementById('btn2');
b2.onclick =function(){alert("没有用任何上层变量")};
console.dir(b2.onclick);
}
d();
</script>
我也来说说闭包,续例
如果c和d合并一个函数,b2.onclick也保存了变量3.不知是chrome浏览器特有?没有拿其他浏览器测试。反正函数里既然没有使用到变量,浏览器做不做成闭包,缓不缓存局部变量。对于我们使用者来说,没啥影响。这里就不上代码和图了
注意:摘抄于https://www.qdfuns.com/article/17398/68357db148a3aea1b7ac9d7ae071fc2d.html