闭包的由来:
出于种种原因,我们有时候需要得到函数内的局部变量。正常情况下,这是办不到的,只有通过变通方法才能实现。
个人理解:
闭包就是能够读取其他函数内部变量的函数
MDN 对闭包的定义为:
闭包是指那些能够访问自由变量的函数。
那什么是自由变量呢?
自由变量是指在函数中使用的,但既不是函数参数也不是函数的局部变量的变量。
示例如下:
var a = 1;
function foo() {
console.log(a);
}
foo();
foo 函数可以访问变量 a,但是 a 既不是 foo 函数的局部变量,也不是 foo 函数的参数,所以 a 就是自由变量
闭包示例:
示例一
function box(){
var a = 2;
return function(){
console.log(a+3);
}
}
var c = box();
c();
示例二
var Box = function() {
var circle = new Object();
circle.PI = 3.14159;
circle.area = function( r ) {
return this.PI * r * r;
}
return circle;
}
var c = new Box();
console.log(c.area(10));
示例三
var sum
(function () {
var num = 10 , calc
calc = {
add: function() {
return num += 10;
}
}
window.sum = calc;
})();
console.dir(sum.add());
要理解闭包为什么能够访问其它函数的作用域,必须理解Javascript的变量作用域以及执行上下文 [戳这里]
闭包的用途
用途一:模仿块级作用域
(function(num){
//块级作用域
var sum = 0 , i
for(i=0;i<num;i++){
sum+=num;
}
console.log(sum);
return sum
})(7);
用途二:实现缓存
function createCache(){
//1:变量一直保存在内存中
//2:不会污染全局变量
var _cache = {};
return {
setCache: function (k,v) {
if(v !== undefined){
_cache[k] = v;
}
},
getCache: function (k) {
return _cache[k];
},
clearAllCache: function(){
for(var k in _cache){
delete _cache[k];
}
}
}
}
var c = createCache();
c.setCache("age","5000");
console.log(c.getCache("age"))
用途三:更好的封装性
var person = function(){
//变量作用域为函数内部,外部无法访问
var name = "default";
return {
getName : function(){
return name;
},
setName : function(newName){
name = newName;
}
}
}();
console.log(person.name);
console.log(person.getName());
person.setName("hello");
console.log(person.getName());
闭包的缺陷
缺陷一:引用的变量不能获取正确的值
function box(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = function(){
return i;
};
}
console.log(result[1]());
console.log(result[3]());
console.log(result[5]());
}
box();
解决办法
function box(){
var result = new Array();
for (var i=0; i < 10; i++){
result[i] = (function(num){
return num;
})(i);
}
console.log(result[1]);
console.log(result[3]);
console.log(result[5]);
}
box();
缺陷二:使用不当容易造成内存泄漏
闭包不在使用时,要及时解除引用(将引用赋值为null)