这个文章纯属是个人的理解。。。以便以后回来查看
js闭包作用:->让js拥有了私有变量,避免了全局污染。。
可以用的地方:->多个商品的件数,互不影响。可以写一个闭包方法。。
什么是闭包:->例如:我们经常会遇到的问题:
var list=document.querySelectorAll("ul li")
for(var i=0;i
- list[i].οnclick=function(){
alert(i);
//对这个元素进行操作的代码……
}
}
结果:弹出list.length次alert(list.length-1);没有我们想要的alert(1)……alert(list.length-1);
原因:因为js不像其他的编程语言,for ,if,等都是一块独立的作用域,而js只有函数是作用域块,for循环是没有作用域的。而js解析机制是,所有的变量一开始会解析为underfined,所有的函数解析为一个函数作用域块,函数名为指针,等待调用。上面的用例子中是用户触发对应的点击事件的时候,才会去调用这个函数作用域。这个时候,i才开始进入js的解析环境。。。而这个时候i已经是list.length-1了。
结论:所以for在一开始解析循环完后,i就已经等于了list.length-1了,故触发点击事件的时候,解析函数作用域的块。这时候找到的变量是i=list.length-1,故,弹出的结果是alert(list.length-1);
解决方法:闭包的思想
闭包的思想: 这是我个人的理解!闭包在我认为就是有js的作用域这个缺陷而引出一个思想。所以主要从作用域这个方面来想。闭包想要达到的最终目的就是有一个私有变量。而函数作用域是一层一层往上找东西的。不可以从上面拿下面作用域的东西。。闭包就利用这一思想引出的。结合js的解析机制我们很容易就看清了闭包的写法。。完全不必要去记写法。。。
上面的例子可以写成:
for(var i=0;i
list(i)//把当前的i传下去
function list(i){//上一级作用域的i
list[i].οnclick=function(){
alert(i);//只有这里能修改i的值,其他地方修改不了。所以该i的值成为他的私有变量。
//对这个元素进行操作的代码……
}
}
}
//闭包2: function fun(){ var ss=1;//可以说是局部的作用域的变量,外部不能修改 function funChildren(){ ss+=1;//修改了局部量ss让ss成为了引用该方法对象的私有变量。 alert(ss); } return funChildren;//和外界联系起来操作私有变量的结果.返回的是一个操作函数的指针。 } var a=fun()//;-》得到内部函数的指针,建立一个新的scope a() ;//ss=2 a();//ss=3 var b=fun(); b();//2; fun();//没有值;->返回的只是一个函数的指指针并没有调用。 //为什么两次引用都是改变同一个变量的位置呢?因为变量的作用域一直不能释放,就是不能来及回收,一直在引用,故再次调用的时候,会直接修改变量。 //这是闭包的最重要的地方: //耗费内存,除非自己赋值为null,但是能永久保存变量。可以创建多个对象,他们拥有相同的方法流程,但是互不影响。
====================================================================================================================================
面试中:不可避免的会问到闭包的使用,什么是闭包的问题,以及会让我们闭包的笔试题:
笔试题:其实闭包的思想,没有那么难,我们要看轻它,不要用这么复杂的思想:函数嵌套函数。应该从解析机制结合作用于来看。
(1):既然是函数:->需要调用(没有的话,根本不需要看这段代码!)
(2):有引用了:返回的是自调函数,还是一个函数指针,还是一个函数方法。(没有返回,这段代码也不需要看!)
(3):这个时候就简单了,就看返回值就可以了。然后就可以用平常的解析思想去想了。
(4):当然还要考虑一下它的回收机制,赋值为null后,再次调用。。
========================================================================
终于写完了(也终于捋顺了),欢迎大神们给我指出错误。。。