什么是闭包?

本文深入浅出地介绍了闭包的原理,包括其作为函数和词法作用域的结合、作用域链的运作。通过实例展示了闭包如何封装数据和暂存状态,并剖析了经典案例和改造版本。理解闭包在JavaScript等编程语言中的关键作用。
摘要由CSDN通过智能技术生成

一、闭包的概念

简单来说:

闭包就是一个函数 + 它的词法作用域上要找的变量。

词法作用域:

  • 函数在执行的过程中,先从自己的内部作用域找变量;
  • 在自己的内部没有找到的话,就到这个函数声明所在的作用域(即词法作用域)里面去找,依次向上;(最后也没有找到的话就是undefined或报错)
  • 找到的变量是变量当前的状态,而不一定是声明时的状态;

作用域链:作用域链,是由当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。

闭包使用的意义:

1.封装数据

2.暂存数据

二、闭包的案例

经典案例:

function car(){
  var speed = 0
  function fn(){
    speed++
    console.log(speed)
  }
  return fn
}

var speedUp = car()
speedUp()  //1
speedUp()  //2

案例一:

var fnArr = []
for(var i = 0; i < 10; i++){
  fnArr[i] = function(){
    return i
  }
}
console.log(fnArr[3]())  //10

理解:fnArr是一个空数组,然后去遍历这个数组,遍历的时候给数组赋值,这个数组的值为一个匿名函数,fnArr[3]指向的是一个函数,在for循环中遍历的时候,将i已经赋值了,但是在function()中并没有赋值变量i,所以在function中找不到的时候就去它的词法作用域(for循环没有作用域,所以即是全局作用域)里面去找,因为for循环执行完后i的值为10,所以最终输出的结果就为10。

改造:

case 1:
var fnArr = []
for(var i = 0; i < 10; i++){
  fnArr[i] = (function(j){
    return function(){
      return j
    }
  })(i)
}
console.log(fnArr[3]())  //3

case2:
var fnArr = []
for(var i = 0;i < 10; i++){
  (function(i){
    fnArr[i] = function(){
      return i
    }
  })(i)
}
console.log(fnArr[3]())  //3

case3:
var fnArr = []
for(let i = 0; i < 10; i++){
  fnArr[i] = function(){
    return i
  }
}
console.log(fnArr[3]())  //3

案例二:封装一个car

var Car = (function(){
  var speed = 0
  function set(s){
    speed = s
  }
  function get(){
    return speed
  }
  function speedUp(){
    speed++
  }
  function speedDown(){
    speed--
  }
  return {
    setSpeed: setSpeed,
    get: get,
    speedUP: speedUp,
    speedDown: speedDown 
  }
})()
Car.set(30)
Car.get()  //30
Car.speedUp()
Car.get()  //31
Car.speedDown()
Car.get()  //30

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值