JS闭包

闭包的概念

在高程三中对闭包的定义是这样的:闭包是指有权访问另一个函数作用域中变量的函数。其实就是函数A返回了一个函数B,并且函数B使用了函数A的变量,函数B就被称为闭包。

function A(){
  var a = 'a';
  function B(){
    alert(a)
  }
  return B
}

在js中变量的作用域分为两种:全局变量和局部变量

var n = 123;
function fn(){
  alert(n)
}
fn();  //123

在函数内部可以直接访问全局变量,但要在外部访问函数内部的变量呢?

function fn(){
  var n = 123;
}
alert(n);  //n is not defined   

可以看到直接报错了,显示n没有被定义,由于种种原因我们需要得到内部变量,我们可以在函数内部再定义一个函数,然后把这个函数返回出来,这样我们能就可以取到函数内部变量

function fn(){
  var n = 123;
  function fn2(){
    console.log(n)
  }
return fn2
}
var result = fn();
result();  //123

在上面代码中fn()的所有局部变量相对于fn2()是可见的,但反过来就不行,fn2()的局部变量对于fn()就是不可见的,如此我们就可以把fn2作为返回值,在fn外部就可以访问fn内部的变量了。
这就是“链式作用域”:子对象可以一级一级的向上寻找所有父对象的变量,所以所有父对象的变量对子对象都是可见的,反之则不行。

闭包的用途

闭包可以被用在很多地方,它最大的用处有两个:一个是上文提到的在函数外部获取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。我们会经常遇到这种情况:

for(var i=0; i <= 5; i++){
  setTimeout(function (){
      console.log(i)
   },1000)
}

首先因为setTimeout()是个异步函数,所以会先把循环全部执行完毕,这时候i就等于6了,所以会输出一堆的6.要解决这个问题就要用到闭包:

for (var i=0; i <= 5; i++){
  (function (n){
    setTimeout(function (){
      console.log(n)
    },1000)
  })(i)
 
}

其实要解决这个问题还有两种方法,第一种就是使用setTimeout()的第三个参数

for (var i=0; i <= 5; i++){
  setTimeout(function (n){
      console.log(n)
  },1000,i)
}

还有一种就是使用let声明变量,let会创建一个块级作用域

for (let i=0; i <= 5; i++){
  setTimeout(function (){
      console.log(i)
  },1000)
}

使用闭包的注意点

闭包会使函数的变量都保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE浏览器会造成内存泄漏。所以在退出函数之前应把不使用的局部变量清空。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 迎新年,过个充满着意义充满着快乐的新年下面是我们贺新年儿童绘画图片,精致的儿童画中展现出新年的特色,一个具有着韵味...
    陈珍1020阅读 3,964评论 0 0
  • 十一回家,晚上去看了看大槐树村的七彩水乡部分景点,感觉这景色真不错。特别是灯光秀,看完觉得很震撼。又上玻璃栈...
    芳菲依旧赵丽芳阅读 4,314评论 2 10

友情链接更多精彩内容