什么是闭包和如何使用闭包?

一、概念

闭包就是能够读取其他函数内部变量的函数。例如在javascript中,只有函数内部的子函数才能读取局部变量,所以闭包可以理解成“定义在一个函数内部的函数”。在本质上,闭包是将函数内部和函数外部连接起来的桥梁。

二、特性

  1. 函数嵌套函数

  2. 函数内部可以引用函数外部的参数和变量

  3. 参数和变量不会被垃圾回收机制回收

三、用法

1. 函数作为返回值

function closure(num) {
    
    
  var count = num
  // t()使用
  // return function getCount() {
    
    
  //   return count++
  // }
  return {
    
    
    plus: function() {
    
    
      return count++
    },
    minus: function() {
    
    
      return count--
    },
    getCount: function() {
    
    
      return count
    }
  }
}
var t = closure(0)
console.log('初始值:' + t.getCount())
t.plus()
console.log('plus后:' + t.getCount())
t.minus()
console.log('minus后:' + t.getCount())

在这里插入图片描述

(1)经典例子-定时器与闭包

1.1 实现依次输入0 1 2 3 4
for (var i = 0; i < 5; i++) {
    
    
  // var则输出5个5,改成let按顺序输出0-4
  setTimeout(() => {
    
    
    console.log(Date.now() + ' ' + i)
  }, 100)
}

在这里插入图片描述

1.2 引入闭包来保存变量j,将setTimeout放入立即执行函数中,将for循环中的循环值j作为参数传递,100毫秒后同时打印出0 1 2 3 4
for (var j = 0; j < 5; j++) {
    
    
  (function(j) {
    
    
    setTimeout(() => {
    
    
      console.log(Date.now() + ' ' + j)
    }, 100)
  })(j)
}

在这里插入图片描述

1.3 那如果我们想实现每隔100毫秒分别依次输出数字,又该怎么改呢?
for (var k = 0; k < 5; k++) {
    
    
  (function(k) {
    
    
    setTimeout(function() {
    
    
      console.log(Date.now() + ' ' + k)
    }, 100 * k)
  })(k)
}

在这里插入图片描述

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

2. 闭包作为参数传递

 // 第一种写法
 function fun2() {
    
    
   var num = 24
   console.log(++num)
 }
 function fun1(fun) {
    
    
   fun()
 }
 fun1(fun2)
 // 输出结果
 // 25

 // 第二种写法(匿名函数回调)
 void (function(fun) {
    
    
   fun()
 })(fun2)
 // 输出结果
 // 25

总结:

优点:
  1. 可以访问到函数内部的局部变量
  2. 可以避免全局变量的污染
  3. 这些变量的值始终保持在内存中,不会在外层函数调用后被自动清除。
缺点:
  1. 会增大内存使用量,滥用闭包会影响性能,导致内存泄漏等问题。
注意:在退出函数之前,将不使用的局部变量全部删除,可以使变量赋值为null。

猜你喜欢

转载自blog.csdn.net/qq_45616003/article/details/124967412