JavaScript闭包初探
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JavaScript闭包初探相关的知识,希望对你有一定的参考价值。
闭包使用的代码部分参考了W3C和饥人谷公开课,谢谢。
1.什么是闭包?
W3C:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量。
要较好理解闭包,除了形式本身,还应先理解:JS没有块级作用域;JS的内存回收机制(可见JavaScript作用域)。
2.闭包的例
闭包是一种结构,getName引用了外部变量name,形成闭包。第9行把name赋给变量whoname,使name在内存中保持。如果没有getName形成闭包,People函数执行完,其name变量就被释放。
1 function People(){ 2 var name = ‘xiaohua‘; 3 function getName(){ 4 return name; 5 } 6 return getName; 7 } 8 9 var whoName = new People();
3.闭包容易引起的bug
var result = []; function foo(){ var i = 0; for(;i<3;i++){ result[i] = function(){ alert(i); } } } foo(); result[0](); //3 result[1](); //3 result[2](); //3
这是因为i始终存在,没有块级作用域,i最后等于3,result数组中的所有函数里的i都指向那个等于3的i。解决办法是给函数传参数。
4.闭包的几个用途
- 隔离作用域
JS虽然没有块级作用域,但是有函数作用域。为了使变量之间不会有命名冲突,使用立即执行函数把作用域隔离。下面的两个作用域内的name互不影响,无意间形成了闭包的结构。如果没有隔离作用域
1 (function(){ 2 var name = ‘aa‘; 3 4 function a(){ 5 return name; 6 } 7 })(); 8 9 (function(){ 10 var name = ‘bb‘; 11 12 function a(){ 13 return name; 14 } 15 })();
- 作计数器
1 var counter = function(){ 2 var count = 0; 3 return function(){ 4 return ++count; 5 }; 6 }; 7 8 var countAdd = counter(); // function(){ return ++count; }; 9 countAdd(); //1 10 countAdd(); //2 11 alert(countAdd()); //3
- 声明私有变量
JS本身没有私有变量、公共变量,静态变量的,都是模拟实现。下面如果把name作为People的属性,就无法实现私有。
1 var People = (function(){ 2 var name = "xiaohua"; 3 function People(){}; 4 People.prototype = { 5 getName:function(){ 6 return name; 7 }, 8 setName:function(newName){ 9 name=newName; 10 } 11 }; 12 return People; 13 })(); 14 15 var p = new People();
以上是关于JavaScript闭包初探的主要内容,如果未能解决你的问题,请参考以下文章
PHP闭包(Closure)初探(转载 http://my.oschina.net/melonol/blog/126694?p=2#comments)