闭包

来源:互联网 发布:新理念网络教学平台 编辑:程序博客网 时间:2024/05/21 11:29
今天抽时间好好整理了一下之前理解模棱两可的闭包,可以说这是一个在面试中经常会被问到的点。我对闭包之前的理解是:闭包就是指有权访问另一个函数作用域中的变量的函数。但是网上众说纷纭,有些也不知所云。创建闭包最常见方式,就是在一个函数内部创建另一个函数。下面的例子就是一个闭包:


function fun(){
  var a = 1,b = 2;
  
  function closure(){
    return a+b;
  }
  return closure;
}


闭包的作用域链包含着它自己的作用域,以及包含它的函数的作用域和全局作用域。
闭包的注意事项:


通常,函数的作用域及其所有变量都会在函数执行结束后被销毁。但是,在创建了一个闭包以后,这个函数的作用域就会一直保存到闭包不存在为止。


闭包只能取得包含函数中任何变量的最后一个值,这是因为闭包所保存的是整个变量对象,而不是某个特殊的变量。


function test(){
  var arr = [];
  for(var i = 0;i < 10;i++){
    arr[i] = function(){
      return i;
    };
  }
  for(var a = 0;a < 10;a++){
    console.log(arr[a]());
  }
}
test(); // 连续打印 10 个 10


为什么返回的i而不是i对应的值,主要是因为闭包中局部变量是引用而不是拷贝,也就是说,这个时候的i仅仅只是i的引用而不是i的值。而因为是i的引用,所以到了外部函数执行完毕后(i已经加到10了),这个时候,i才被赋值给result数组,而此时,i的值为10


对于上面的情况,如果我们改变代码如下:


function test(){
  var arr = [];
  for(let i = 0;i < 10;i++){  // 仅在这里作出了改动
    arr[i] = function(){
      return i;
    };
  }
  for(var a = 0;a < 10;a++){
    console.log(arr[a]());
  }
}
test(); // 打印 0 到 9


关于”闭包中局部变量是引用而不是拷贝”,再举个例子:


function say888() {
    var num = 887;
    var sayAlert = function() { alert(num); }
    num++;
    return sayAlert;
}


很明显,返回的是888,所以闭包中局部变量是引用而不是拷贝。


匿名函数最大的用途是创建闭包,并且还可以构建命名空间,以减少全局变量的使用。从而使用闭包模块化代码,减少全局变量的污染,增强了网页的安全性。


闭包的缺陷


1、闭包的缺点就是常驻内存会增大内存使用量,并且使用不当很容易造成内存泄露。


2、如果不是因为某些特殊任务而需要闭包,在没有必要的情况下,在其它函数中创建函数是不明智的,因为闭包对脚本性能具有负面影响,包括处理速度和内存消耗。
0 0
原创粉丝点击