最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 作为一名前端搬砖人,提起闭包我就心梗。

    正文概述 掘金(勾崽)   2021-01-18   459

    作为一名前端搬砖人,提起闭包我就心梗。

    我听得最多的一句话就是,“闭包,只可意会不可言传”。

    简单来说,闭包就是指有权访问另一个函数作用域中的变量的函数。最常见的形态就是在一个函数的内部创建另一个函数。

    结构

    1. 外部函数的返回结果是一个函数,暂且称为内部函数。

    2. 内部函数中使用了外部函数中的变量(成员)。

    现象

    1. 外部函数执行结束后,被内部函数使用的变量(成员)不会被销毁释放。

    2. 生命周期:在整个代码执行结束时才销毁。

    3. 作用域:只能在函数内部访问。

    目的

    1)每次去执行返回的内部函数,都可以使用该变量(成员)。并且该变量(成员)的值可以变化,也就是说,该变量(成员)可以在函数多次执行过程中保存状态。在其它一些语言中称为静态变量。例:记录函数调用次数。

    2)该变量可以被返回的内部函数访问。但是外部其它代码无法访问,防止意外修改,起到了保护作用。

    Demo

    例1:

    // 闭包
    function makeFn() {
        let msg = '函数作为返回值'
        return function() {
            console.log(msg)  // 内部函数访问外部函数的 msg
        }
    }​
    
    // 外部函数 makeFn 执行完, 应清理所有, 但其 msg 被 fn 使用, 所以 msg 不会销毁
    const fn = makeFn()
    fn() // 第一,msg 可以在 fn 中反复使用
    console.log(msg)  // 第二,msg 在外部这里是访问不到的,它被保护了起来
    

    例2:

    // 闭包
    function once (fn) {
        let done = false
        return function () {
            if (!done) {   // 使用(引用)了外部函数的变量
                done = true
                fn.apply(this, arguments)
            }
        }
    }​
    
    let pay = once(function (money) {
      console.log(`支付: ${money} RMB`)
    })​
    
    pay(5)
    pay(5)
    

    例3:

    /*
      求数字的平方
        pow(5, 2)
        pow(4, 2)
      可以把 2 固定下来
    */
    function makePower(power) {
        return function (number) {
            return Math.pow(number, power)
        }
    }​
    
    // 返回 求平方 的函数
    let power2 = makePower(2)
    console.log( power2(4) )  // 4的平方等于16
    console.log( power2(5) )  // 5的平方等于25​
    
    // 返回 求立方 的函数
    let power3 = makePower(3)
    console.log(power3(4))    // 4的立方等于64
    console.log(power3(5))    // 5的立方等于125
    
    ​/*
      我的理解:
          power 作为参数,理解为外部函数的局部变量
          内部函数中引用了它,内部函数被返回
          所以,这是闭包的结构
          
          函数参数的灵活性不同, 有的经常变, 有的偶尔变
          可以把多参数的函数, 细粒度一些, 如上面代码
    */
    
    ​/*
    Call Stack 调用栈
    Scope 作用域
      Local  局部作用域
      Global 全局作用域
      通过var定义的变量会在全局
      Script 通过let定义的变量可以在这个位置看到
    Closure (makePower)  说明这个闭包引用了 makePower 外部函数中的变量(成员)
      内部函数执行时, 才可以看到闭包相关内容, 即看到它所引用外部函数中的内容
    */
    

    例4:

    /*
      不同级别员工的工资
      生成计算工资的函数. 不同级别员工 基本工资不同
         基本工资 base         12000, 15000 
         绩效工资 performance
    */
    function makeSalary (base) {
      return function (performance) {
        return base + performance
      }
    }​
    
    // 基本工资为 12000 的  工资计算函数
    let salaryLevel1 = makeSalary(12000)
    // 基本工资为 15000 的  工资计算函数
    let salaryLevel2 = makeSalary(1500
    ​
    console.log(salaryLevel1(2000))  // 总工资 14000
    console.log(salaryLevel2(3000))  // 总工资 18000
    

    不管你的理解如何,只要你能写出闭包的案例,你就已经一脚踏入了前端的世界。


    起源地下载网 » 作为一名前端搬砖人,提起闭包我就心梗。

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元