闭包*****

***************************为什么要学习闭包*********************
 // 变量? 向【内存】中申请的一块空间  
    // 变量的生命周期:变量从产生到释放的过程。
    // 全局变量:程序关闭时,全局变量会被释放。
    // 局部变量:在函数调用执行结束后,会被释放。
    // GC(Garbage Collection)→ 垃圾回收机制→ 生活中保洁→清理没有用的数据。

    var a = 123;
    function fn() {
      // var b;
      console.log(a);//123
      console.log('函数开始')
      var b = 456;
      console.log(b);
      console.log('函数结束')
    }
    fn();   // 函数内部→ 开始→ 创建了变量b→使用了变量b→结束→ 释放了变量b
    // fn();   // 函数内部→ 开始→ 创建了变量b→使用了变量b→结束→ 释放了变量b
    // fn();   // 函数内部→ 开始→ 创建了变量b→使用了变量b→结束→ 释放了变量b
    // console.log(b); // 报错

    // 为什么外部无法访问内部的局部变量?
    // ① 作用域的规则
    // ② 变量没有创建或者被释放
    **********************************作用域链*****************************
    // 作用域链:
    function fn() {
      var a = 1, b = 2;
      function fn1() {
        var b = 22, c = 33;
        function fn2() {
          var a = 100;
          console.log(a, b, c);
        }
        fn2();
      }
      fn1();
    }
    fn();
    // 作用域链:访问变量的过程。 从内向外。
    // 反之不行。 
    // console.log(a,b,c);//报错

    // 需求:在外部可以操作(间距)到内部的变量。
    // 要保证内部的变量不会被释放(延长局部变量的生命周期),并且变量已经被创建。
    // 实现技巧:闭包!
    ************************************如何实现闭包*****************************
    function fn() {
      var a = 123;  // 局部变量
      // console.log(a)
      // 子函数→卧底
      function son () {
        console.log('更改之前:' + a);
        a = a + 10;
        console.log('更改之后:'  + a);
      }

      // 返回
      return son;  // 将内部函数的地址返回
    }  

    var cyqz = fn();
    cyqz();
    // cyqz();
    // cyqz();

    // a不要被释放,每次对a可以实现加减乘除,在a原有值的基础上
    *******************************实现闭包的规则*************************
     <script>
    function fn() {
      var a = 123;  // 局部变量
      return function () {
        console.log('更改之前:' + a);
        a = a + 10;
        console.log('更改之后:' + a);
      };
    }

    var cyqz = fn();
    cyqz();
    // cyqz();
    // cyqz();

    // a不要被释放,每次对a可以实现加减乘除,在a原有值的基础上

    // 如何检测一个代码中是否存在闭包?
    // 【1. 调试:】
    // 【2. 规则:】
    // ①. 外层函数  和  子函数

​    // ②. 外层函数必须有局部变量

​    // ③. 子函数要操作外层函数的局部变量

​    // ④. 让子函数和外部产生关联。


    // 扩展:为什么有了闭包,局部变量没有被释放
    // GC回收没有用的数据
    // 闭包:外部环境间接操作局部变量,说明局部变量被使用,是有用的数据。
    // 闭包的缺点:不当的使用闭包,会造成内存泄露→消耗内存。
    // 手动释放:把外部变量设置为null。局部变量会被释放。
    
    // null 空对象
    // GC会去回收变量为null内存。


  </script>
  ************************************检测闭包*********************************
  // 测试1
    var name = "The Window";
    var object = {
      name: "My Object",
      getNameFunc: function () {
        var a = this;
        console.log(a);//Object对象
        // 此时的that=this。而this指向object,所以that指向object。
        // 无论你执行多少次,他都是对object的引用,所以输出My Object
        return function () {
          console.log(this.name)//Thewindow
          // javascript是动态(或者动态类型)语言,this关键字在执行的时候才能确定是谁。
          // 所以this永远指向调用者,即对‘调用对象‘者的引用。
          // 第一部分通过代码:object.getNameFunc()调用返回一个函数。这是个返回的函数,
          // 它不在是object的属性或者方法,此时调用者是window。因此输出是 The Window
        };
      }
    };
    var fn = object.getNameFunc();
    fn(); 
// 你好,谢谢你的回答,但我有个疑问:第一个中不能理解为闭包的第一作用域链是闭包本身,
// 然后是闭包外面的函数,之后是window对象么?它不能像原形链那样一直向上寻找么?
// 追答
// 因为执行代码object.getNameFunc()之后,它返回了一个新的函数,
// 注意这个函数对象跟object不是一个了,可以理解为全局函数。
// 所以它的name属性不会是My Object。这个例子只能作为关键字this的教材。
// 如果作为寻找变量的例子就不好了
    // 测试2
    // var name = "The Window";
    // var object = {
    //   name: "My Object",
    //   getNameFunc: function () {
    //     var that = this;
    //     return function () {
    //       console.log(that.name);// 这个that就是对象了。
    //     };
    //   }
    // };
    // var fn = object.getNameFunc();
    // fn();
    **********************************
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值