js高级特性--闭包

js高级特性–闭包

前置知识

变量声明

  • 基本数据类型

    var a = 12
    var b = a
    b = 13
    

在这里插入图片描述

  • 引用数据类型

    var a = {n: 12}
    var b = a
    b.n = 13
    console.log(a)       // { n: 13 }
    

在这里插入图片描述

  • 函数的声明和调用

    • 函数声明

      ...
      const A = function(a) {
          ...
      }
      ...
      

      在这里插入图片描述

      函数声明步骤: 1、声明作用域[[scope]] 2、声明形参 3、存储代码块

    • 函数调用

在这里插入图片描述

> 函数调用步骤: 1、形成私有的执行上下文   2、初始化作用域链  3、形参赋值   4、代码执行

js作用域(es5)

js中作用域分为全局作用域和局部作用域(函数作用域)

  • 全局作用域

    任何地方都能被访问

    var num = 100
    function f1() {
      console.log(num);
    }
    f1()      // 100
    
  • 函数作用域

    在固定的代码片段中才能被访问

    function f2() {
      var num = 200
    }
    f2()
    console.log(num);  //demo.html:13 Uncaught ReferenceError: num is not defined
    
    • 注意 定义的变量不使用var关键词 则为全局作用域

      function f2() {
        num = 200    // 定义的变量为全局作用域
      }
      f2()
      console.log(num);  // 200
      

作用域链

变量寻找过程: 作用域f1 —》 作用域f2 —》 全局作用域 (当前作用域找不到值就会向上一级作用域找,直至找到为止,形成作用域链)

var a = 1              // 变量a为全局作用域
function f1() {
  var b = 2            // 变量b为f1作用域
  function f2() {
    var c = 3          // 变量c为f2作用域
    console.log(a);
  }
  f2()
}
f1()    //  输出1

// 执行函数f2  打印变量a  在f2作用域中没有变量a  向上找f1作用域  f1作用域没有变量a 向上找全局作用域 存在变量a  正确打印

思考

作用域链机制可以让函数作用域内访问全局作用域的变量

  • 反之如何实现在全局作用域内访问函数作用域中的变量

    function f1() {
      var a = 1
      var b = 2
      function f2 (){      
        console.log(a+b);
      }
      return f2
    }
    var f3 = f1()
    f3()
    
    // f2函数嵌套在f1函数内部,所以f1内部的所有变量对于f2都是可访问的(作用域链机制),当f2作为返回值,我们就可以在全局作用域中访问函数作用域中的变量了。
    
    

闭包概念

  • 思考中的f3函数就是闭包,闭包就是可以访问其他函数内部变量的函数

  • 因为在js中只有函数内部的子函数才能访问局部变量,所以闭包可以理解为函数内部的函数

  • 闭包本质就是函数内部与函数外部连接的桥梁

闭包的用途

  1. 可以访问函数作用域中的变量(上文思考中)

  2. 让变量的值始终保存在内存中

    • 没有闭包的情况下

      function f1() {
        var a = 1
        a++
        console.log(a);
      }
      f1()                       // 输出为2
      f1()                       // 输出为2  因为每次调用后变量会被垃圾回收机制回收
      
      // f2函数中的a是自己的函数作用域  所以f2执行完就回收变量a
      
    • 存在闭包的情况下

      function f1() {
        var a = 2
        return function () {
          a++
          console.log(a);
        }
      }
      var f2 = f1()
      f2()                                     // 输出为3
      f2()		                             // 输出为4
      
      // f2 函数中的a访问的是f1中的作用域 所以f2执行完并不会回收变量a
      

练习

  • 练习1

    var name = "The Window";
    var object = {
      name : "My Object",
      getNameFunc : function(){
        return function(){
          return this.name;
        };
      }
    };
    alert(object.getNameFunc()());   //  输出为  The Window
    
    var name = "The Window";
    var object = {
     name : "My Object",
     getNameFunc : function(){
       var that = this;
       return function(){
         return that.name;
       };
    
      }
    
     };
    
     alert(object.getNameFunc()());   //  输出为 My Object
    
  • 练习2

    let a = 0
    b = 0
    function A(a) {
        A = function(b) {
            console.log(a + b++)
        }
        console.log(a++)
    }
    A(1)     // 输出为1
    A(2)     // 输出为4
    

    运行过程

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值