js闭包的实际使用场景

什么是闭包?


1. 定义

  • 当函数可以记住并访问所在的词法作用域,即使函数是在当前词法作用域之外执行,这时就产生了闭包(词法作用域:js的作用域特点,在写代码时将变量和作用域块写在哪里来决定的,)

2、举例

function foo () {
  let index = 0
  function baz () {
    return index += 1
  }
  return baz
}

let bar = foo()
bar() // 1
bar() // 2

 

  •  这样就实现了一个闭包,我每次调用bar的时候访问得都是同一个index,所以会出现一个累加的值
  •  原本foo执行完毕之后会被回收,现在因为bar持有对foo的引用,所以foo并不会被回收,如果不需要的时候可以手动释放


哪些情况下用到闭包?

 

  1. 使用任何方式对函数变量进项传递,在别处调用都形成闭包,下面举两个实际中常用到的例子
  • 例如回调函数,有时候我们希望对异步请求的数据结果进行操作,例如对一个异步返回的数组,求最大值
function foo (callback) {
  new Promise((resolve) => {
    resolve([1, 2, 3, 4])
  }).then(res => {
    callback(res)
  })
}

function bar (arr) {
  arr.push(10) // arr [1, 2, 3, 4, 10 ]
  arr.push(6) // arr [ 1, 2, 3, 4, 10, 6 ]
  Math.max.apply(null, arr) // 10 求最大值
}

foo(bar) 
// 这就形成了一个闭包,完全符合闭包的定义

 

  • 实现bind函数:其作用是改变this的指向
// getName 的 this指向foo对象
let foo = {
  name: 'jill'
}
function getName () {
  console.log(this.name)
}
Function.prototype.myBind = function (obj) {
  // 将当前函数的this 指向目标对象
  let _self = this
  return function () {
    return _self.call(obj)
  }
}

let getFooName = getName.myBind(foo)
getFooName() // jill

 

  • 异步循环调用
for (var i = 0; i < 2; i++) {
  (function (i) {
    setTimeout(() => {
      console.log(i)
    })
  })(i)
}


闭包优点和缺点?

1、优点

  • 可以读取函数内部的变量,在任何地方使用,可以实现变量共享
  • 可以封装私有变量,减少全局变量

 
2、缺点

  • 暴露函数内部的变量可以访问和修改
  • 使用闭包的时候原函数会不会被回收,会常驻内存,如果大量使用可能会导致性能问题,所以在使用完毕之后可以手动释放
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值