JavaScript知识点-闭包

1.什么是闭包

  1. MDN给出的定义是:

闭包(closure)是一个函数以及其捆绑的周边环境状态(lexical environment,词法环境)的引用的组合。换而言之,闭包让开发者可以从内部函数访问外部函数的作用域。在 JavaScript 中,闭包会随着函数的创建而被同时创建。

简单来说就是,定义在一个函数内部的函数。其中一个内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

  1. 举一个简单的🌰:
var scope = "global scope" // 全局变量
function init() {
  var scope = "local scope" // 局部变量
  function internalFun() { return scope}
  return internalFun()
}
init() // 结果什么呢?

init() 创建了一个局部变量,并且定义了一个函数internalFun(), 函数internalFun()返回了这个变量的值,最后将函数internalFun()的执行结果返回。注意,internalFun()没有自己的局部变量,然后,因为它可以访问到外部函数的变量,所以在 internalFun()可以使用父函数inint() 中声明的scope变量。
所以输出的结果为为:“local scope”

现在我们对这段代码做一点改动,猜猜会返回什么?

var scope = "global scope"
function init() {
  var scope = "local scope" 
  function internalFun() { return scope }
  return internalFun()
}
init()()

在这段代码中,在init函数后面加了一对括号,init函数现在仅仅返回函数内嵌套的一个函数对象,而不是直接返回结果。
回想一下作用域的基本规则:js函数的执行用到的作用域链是函数定义时候创建的,嵌套的函数internalFun()定义在这个作用于链里,其中的变量scope一定是局部变量,不管在何时何地执行函数internalFun(),这种绑定在执行internalFun()时依然有效。因此最后一行代码输出结果为local scope

2.闭包的特点是什么

  • 函数嵌套函数。
  • 函数内部可以引用外部的参数和变量。
  • 参数和变量不会被垃圾回收机制回收。
2.1 js的垃圾回收机制
  • 如果一个对象不再被引用,那么这个对象那个就会被回收。
  • 如果两个对象相互引用,而不在被第三者所引用,那么这两个对象都会被回收。
2.2闭包的用途
  • 访问函数内部的变量
  • 让变量始终保持在内存中

3.闭包的应用场景

1.使用setTimeout

使用闭包可以保存循环变量或定时器的参数,并确保在回调函数执行时以正确的值进行处理。例如:

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

我们使用立即执行函数创建了一个新的函数作用域,每次循环都将 i 的值传递给立即执行函数的参数 index,从而在定时器回调函数执行时正确地打印每次循环的值。

2.实现私有方法

JavaScript 没有这种原生支持,但我们可以使用闭包来模拟私有方法。私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。例如:

function createPerson(name) {
  const greeting = 'Hello, ' + name;
 
  return {
    sayHello: function() {
      console.log(greeting)
    }
  }
}
 
const person = createPerson('lily');
person.sayHello() // 输出: Hello, lily
person.greeting // undefined
3.递归

闭包在递归算法中经常被使用,可以保存递归中的状态和结果,并确保在每次递归调用时使用正确的值。例如

function factorial(n) {
  if (n === 1) {
    return 1
  } else {
    return n * factorial(n - 1)
  }
}
 
console.log(factorial(5)) // 输出: 120

4.闭包的优缺点

  1. 缺点
  • 可以减少全局变量的定义,避免全局变量的污染
  • 能够读取函数内部的变量
  • 在内存中维护一个变量,可以用作缓存
  1. 优点
  • 会造成内存泄漏,闭包的使用会使函数中的变量一直保存在内存中,内存消耗很大,所以不能随意使用,否则会造成网页的性能问题。解决方法就是:在使用完以后,手动将它赋值为null
  • 闭包可能在父函数外部, 改变父函数内部变量的值。
  • 由于闭包涉及跨作用域的访问,所以会导致性能损失。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值