大家好,我是IT修真院成都分院第8期的学员,一枚正直纯洁善良的WEB前端程序员。今天给大家分享一下闭包是什么,用处如何。
1、闭包是什么?
闭包(closure)是JS中一个较难理解的一个概念,JS函数的执行依赖于变量作用域, 函数对象的内部状态包含函数自身的逻辑,还必须引用当前的作用域链。 函数对象可以相互关联起来,函数体内部的变量可以保存在函数作用域内, 具有这种特性的函数称为闭包。 各种专业文献上的"闭包"(closure)定义非常抽象,很难看懂。 我的理解是,闭包就是能够读取其他函数内部变量的函数。 由于在Javascript语言中,只有函数内部的子函数才能读取局部变量, 因此可以把闭包简单理解成"定义在一个函数内部的函数"。 所以,在本质上,闭包就是将函数内部和函数外部连接起来的一座桥梁。---阮一峰
2、闭包的作用?
(1)可以读取函数内部的变量
/*使用闭包读取函数内部的变量*/
function f1(){
n = 999;
function f2(){
alert(n);
}
return f2;
}
var result = f1();
result(); //999
(2)让这些变量的值始终保存在内存中
/*使用闭包让函数内部的变量储存在内存中*/
function f1(){
n = 999;
nAdd = function(){
n+=1;
};
function f2(){
alert(n);
}
return f2;
}
var result = f1();
result();//999
nAdd();
result();//1000
3、常见的问题?
window.onload = function(){
var el = document.getElementById("id");
el.onclick = function(){
alert(el.id);
}
}
这段代码会造成内存泄漏,为什么?
执行这段代码的时候,将匿名函数对象赋值给el的onclick属性;然后匿名函数内部又引用了el对象,存在循环引用,所以不能被垃圾回收机制回收;
解决办法:
window.onload = function(){
var el = document.getElementById("id");
var id = el.id; //解除循环引用
el.onclick = function(){
alert(id);
}
el = null; // 将闭包引用的外部函数中活动对象清除
}
4、讨论
var name = "The Window";
var object = {
name : "My Object",
getNameFunc : function(){
return function(){
return this.name;
};
}
};
alert(object.getNameFunc()());//the window
按照闭包的原理,输出的不应该是 my object吗?
答: 匿名函数的执行环境具有全局性,因此其 this 对象通常指向 window。
第二个例子中的的nAdd这个函数在函数f1内部,为什么说他是一个闭包呢?
答:这是一个函数声明式,但是没有var,所以这是一个全局变量,等于从外部访问内部变量,所以这是一个闭包。
使用闭包有什么好处呢?
答:可以从外部调用函数内部变量,避免污染全局变量。