什么是闭包?

£神魔★判官ぃ 2022-11-22 05:27 252阅读 0赞

闭包

我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的变量并且可以获得当前包含当前作用域的外层作用域下的变量,反之则不能,也就是说在外层作用域下无法获取内层作用域下的变量,同样在不同的函数作用域中也是不能相互访问彼此变量的,那么我们想在一个函数内部也有限权访问另一个函数内部的变量该怎么办呢?闭包就是用来解决这一需求的,闭包的本质就是在一个函数内部创建另一个函数

闭包有3个特性
①函数嵌套函数
②函数内部可以引用函数外部的参数和变量
③参数和变量不会被垃圾回收机制回收

1函数作为返回值

  1. function a(){
  2. var name = '哈哈';
  3. return function(){
  4. return name;
  5. }
  6. }
  7. var b = a()

a()中的返回值是一个匿名函数,这个函数在a()作用域内部,
所以它可以获取a()作用域下变量name的值,将这个值作为返回值赋给全局作用域下的变量b,实现了在全局变量下获取到局部变量中的变量的值

2 内存消耗问题

  1. function fun(){
  2. var num = 3
  3. return function(){
  4. var n=0;
  5. console.log(++n)
  6. console.log(++num)
  7. }
  8. }
  9. var fn1 = fun()
  10. fn1() //1 4
  11. fn1() //1 5

一般情况下,在函数fun执行完后,就应该连同它里面的变量一同被销毁,但是在这个例子中,匿名函数作为fun的返回值被赋值给了fn1,这时候相当于fn1=function(){var n = 0 … },并且匿名函数内部引用着fun里的变量num,所以变量num无法被销毁,而变量n是每次被调用时新创建的,所以每次fn1执行完后它就把属于自己的变量连同自己一起销毁,于是乎最后就剩下孤零零的num,于是这里就产生了内存消耗的问题

3 定时器闭包

  1. for(var i=0; i<5; ++i){
  2. (function (i){
  3. setTimeout(function(){
  4. console.log(i + " ");
  5. },100);
  6. }(i));
  7. }
  8. // undefined 0 1 2 3 4

引入闭包来保存变量i,将setTimeout放入立即执行函数中,将for循环中的循环值i作为参数传递,100毫秒后同时打印出1 2 3 4 5

  1. for(var i=0; i<5; ++i){
  2. (function (i){
  3. setTimeout(function(){
  4. console.log(i + " ");
  5. },i*100);
  6. }(i));
  7. }
  8. // undefined 0 1 2 3 4

相当于同时启动3个定时器,i*100是为4个定时器分别设置了不同的时间,同时启动,但是执行时间不同,每个定时器间隔都是100毫秒,实现了每隔100毫秒就执行一次打印的效果。

4.闭包作为参数传递

  1. var num = 15
  2. var fn1 = function(x){
  3. if(x > num){
  4. console.log(x)
  5. }
  6. }
  7. void function(fn2){
  8. var num = 100
  9. fn2(30)
  10. }(fn1)

函数fn1作为参数传入立即执行函数中,在执行到fn2(30)的时候,30作为参数传入fn1中,这时候if(x>num)中的num取的并不是立即执行函数中的num,而是取创建函数的作用域中的num这里函数创建的作用域是全局作用域下,所以num取的是全局作用域中的值15,即30>15,打印30

闭包的好处与坏处

好处
①保护函数内的变量安全 ,实现封装,防止变量流入其他环境发生命名冲突
②在内存中维持一个变量,可以做缓存(但使用多了同时也是一项缺点,消耗内存)
③匿名自执行函数可以减少内存消耗

坏处
①其中一点上面已经有体现了,就是被引用的私有变量不能被销毁,增大了内存消耗,造成内存泄漏,解决方法是可以在使用完变量后手动为它赋值为null;
②其次由于闭包涉及跨域访问,所以会导致性能损失,我们可以通过把跨作用域变量存储在局部变量中,然后直接访问局部变量,来减轻对执行速度的影响

发表评论

表情:
评论列表 (有 0 条评论,252人围观)

还没有评论,来说两句吧...

相关阅读

    相关 什么

    我们都知道一个概念。 在JS当中,一个函数可以访问其外部的变量资源。 ![format_png][] 一个典型的代码   但以下这种情况会出错。 fun

    相关 什么

    闭包 我们都知道,js的作用域分两种,全局和局部,基于我们所熟悉的作用域链相关知识,我们知道在js作用域环境中访问变量的权利是由内向外的,内部作用域可以获得当前作用域下的

    相关 什么

            \----本文摘自programming in  lua 如果在一个内部函数里,对在外部作用域(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包

    相关 什么

    什么是闭包? 简单来说,闭包是指外部可以访问另一个函数作用域内的变量的函数,一般是定义在外层函数中的内层函数。 为什么需要闭包? 局部变量无法共享和长久的保存,而全局变量

    相关 什么

    闭包是指有权访问另一个函数作用域中变量的函数 作用:访问另一个函数作用域中变量 原理:通过匿名式函数把局部变量驻留在内存里,可以减少全局变量的使用 优点是封装性,

    相关 什么

    什么是闭包? 说明 闭包   有些读者可能很好奇,为什么闭包会成为一个独立的概念,以及为什么它需要编程语言提供额外的支持。这些疑惑可以本文中找到答案。

    相关 什么

    1.什么是闭包? 古老定义   闭包(closure),是指函数变量可以保存在函数作用域内,因此看起来是函数将变量“包裹”了起来   那这样说来,包含变量的函数就是闭

    相关 什么

    闭包 定义:闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,通过另一个函数访问这个函数的局部变量,利用闭包可以突破作用链