js中的变量有两种作用域 , 即全局变量和局部变量 .
现在 , 假如我们想用一个变量来进行计数 , 通常的写法如下 :
var count = 0 ;
function addCount(){
count = count + 1 ;
return count ;
}
这样 ,我们每次调用 addCount()
方法就可以进行计数 .
但是! 此时count是个全局变量 , 任何其他函数都可以对其进行修改 , 这样就不能保证数据的安全性 . 于是 , 我们想到了使用局部变量 , 例如:
function addCount(){
var count = 0 ;
count = count + 1 ;
return count ;
}
如果这样写 , 那么每次调用addCount()
方法都会将count置0后重新加1,也就是每次只能得到同一个结果 ,就是 1 .
那么 , 有没有办法既可以做到变量的私有性 , 又可以完成这个计数的需求呢 ? 有! 那就是闭包函数. 例如:
<!DOCTYPE html>
<html>
<body>
<button type="button" onclick="myFunction()">Count!</button>
<p id="demo">0</p>
<script>
var add = (function () {
var counter = 0; // 仅仅首次加载网页文档时执行
return function () {return counter += 1;} // 以后每次调用add()方法执行
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
</script>
</body>
</html>
此处定义变量add是关键 , js中一种自调用的函数定义:
(function(a,b){
return a+b;
})()
这样定义的函数 , 在文档加载时即自行调用 , 称作自调用函数 .
定义方法就是将函数用小括号包裹后 , 在后面跟随另一个小括号即可 .
回到示例中 , var counter = 0;
这条语句仅仅在首次加载网页时执行 , 初始化count = 0
当之后点击button调用add()
方法时 , 通过debug可以发现 , 仅仅执行了return
语句, 即执行了 function(){return counter += 1;}
这样就可以保证 , 只有add()
方法可以改变count的值 , 实现了变量私有化 .
关于闭包函数理解上的重大更新
著作权归作者所有。
商业转载请联系作者获得授权,非商业转载请注明出处。
作者:newraina
链接:https://www.zhihu.com/question/38280516/answer/75853078
来源:知乎
还是先来看之前那个例子:
var add = (function () {
var count = 0;
return function () {
return count += 1;
}
})();
add(); // count = 1
add(); // count = 2
add(); // count = 3
等号右边的不是普通的函数,它被一个括号包裹了,这是立即执行函数,在赋值的时候就被执行了,并且再也不会执行第二次。而它执行的结果,就是返回了下面这个函数:
function () {
return count += 1;
}
这个函数被赋给了add,那么现在,add相当于下面这个东西:
function add () {
return count += 1;
}
count在哪里呢?count还在原来那个立即执行函数中,本来这个立即执行的东西执行过了里面东西就会被引擎回收再也找不到了,可是add引用了里面的一个函数,函数里还有还有一个count,为了add不会出错,引擎就没有回收第一行右边的东西,于是你可以把例子看成下面这个:
var count = 0;
function add () {
return count += 1;
}
这样就可以理解了。
这个add引用的函数,就叫做闭包。
写在最后
知乎 真的是个很神奇的网站 . 上面有各种神奇的问题 , 也有很多神奇的答案 .