您的位置:首页 > Web前端 > JavaScript

JavaScript闭包初探

2016-03-07 11:49 369 查看
闭包使用的代码部分参考了W3C和饥人谷公开课,谢谢。

1.什么是闭包?

W3C:闭包,指的是词法表示包括不被计算的变量的函数,也就是说,函数可以使用函数之外定义的变量

要较好理解闭包,除了形式本身,还应先理解:JS没有块级作用域;JS的内存回收机制(可见JavaScript作用域)。

2.闭包的例

闭包是一种结构,getName引用了外部变量name,形成闭包。第9行把name赋给变量whoname,使name在内存中保持。如果没有getName形成闭包,People函数执行完,其name变量就被释放。

function People(){
var name = 'xiaohua';
function getName(){
return name;
}
return getName;
}

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互不影响,无意间形成了闭包的结构。如果没有隔离作用域

(function(){
var name = 'aa';

function a(){
return name;
}
})();

(function(){
var name = 'bb';

function a(){
return name;
}
})();


作计数器

var counter = function(){
var count = 0;
return function(){
return ++count;
};
};

var countAdd = counter(); // function(){ return ++count; };
countAdd();           //1
countAdd();           //2
alert(countAdd());    //3


声明私有变量

JS本身没有私有变量、公共变量,静态变量的,都是模拟实现。下面如果把name作为People的属性,就无法实现私有。

var People = (function(){
var name = "xiaohua";
function People(){};
People.prototype = {
getName:function(){
return name;
},
setName:function(newName){
name=newName;
}
};
return People;
})();

var p = new People();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: