在前端的面试题关于JavaScript的部分,“闭包”一直是最热门的考点之一。但是很多人对这个知识点都理解的不是很透彻,下面是我对“闭包”的自己的理解。
“闭包”是指有权访问另一个函数作用域中的变量的函数。创建闭包的常见方式是在一个函数内部创建另一个函数。在闭包中,内部函数会将外部函数的活动对象添加到它的作用域链中。
·······································································································································································································································
“闭包”只能取得包含函数中任何变量的最后一个值但是闭包保存的却是整个变量对象。(如下面的例子)
<pre name="code" class="html">function createFunction(){
var result= new array();
for(var i=0;i<10;i++){
reault[i]=function(){
return i;
}
}
return result;
}
在我们看来每个函数都应该返回自己的索引值,但实际上每个函数都返回10.因为每个函数的作用域链中都保存着createFunction()函数的活动对象。他们引用的是同一个变量I,当createFunction()函数返回后,变量i的值是10.此时每个函数都引用着保存变量i的同一个变量对象,所以在每个函数内部i的值都是10.但我们可以创建另一个匿名函数强制让闭包的行为符合预期。如下代码所示:
<pre name="code" class="html">function createFunction(){
var result= new Array();
for(var i=0;i<10;i++){
result[i]=function(num){
return function(){
return num;
};
}(i);
}
}
····································································································································································································································
就是说,使用闭包时,每次接受的参数都是上一次执行的结果,而不是你传进的参数。闭包中的外部函数的作用域一直不会被销毁,直到闭包被销毁。所以闭包的参会一直变化。不使用闭包的话,每次执行都会重新开始,没有记忆的功能。(具体实例请看下面的代码)
e.g:使用闭包的情况:
function creat(start){
return function(){
start++;
return start;
}
}
这时控制台中:var x=creat(3);
x(3); -----------------4
x(3); ------------------5
x(3); --------------------6
e.g:不使用闭包的情况:
function creat(start){
start++;
return start;
}
这时控制台中:var x=creat(3);
x(3); -----------------4
x(3); -----------------4
x(3); ------------------4
······································································································································································································································
在一般的开发中,不建议使用闭包。因为闭包会携带包含它的函数的作用域,因此会比其他函数占用更多的内存。过度使用闭包可能会导致内存占用过多。