JavaScript函数进阶

1 函数的定义和调用

1.1函数的定义方式
1.函数声明方式function关键字(命名函数)

2 this

3 严格模式

4 高阶函数

5 闭包

5.1 变量作用域

变量根据作用域的不同分为两种∶全局变量和局部变量。
1.函数内部可以使用全局变量。
2.函数外部不可以使用局部变量。
3.当函数执行完毕,本作用域内的局部变量会销毁。

5.2 什么是闭包

闭包( closure )指有权访问另一个函数作用域中变量的函数。----- JavaScript高级程序设计

简单理解就是,一个作用域可以访问另外一个函数内部的局部变量。

  <script>
    // 闭包(closure)指有权访问另一个函数作用域中变量的函数
    function fn() {
      var num = 10;
      // fun()函数中可以访问fn函数作用域中的局部变量的num
      function fun() {
        console.log(num);// 10
      }
      fun();
    }
    fn();
  </script>

利用Chrome浏览器查看有没有闭包的产生。点开“Sources”,在语句fn();上打断点后刷新页面。
运行到fn();时,fn()还没有被调用,是在最外层,是全局作用域Window
在这里插入图片描述
点击F11,执行下一步。进入局部作用域 – fn的作用域内。在fn的局部作用域里,有fun函数、num变量和this。
在这里插入图片描述
执行下一步,直到进入fun函数的作用域内(如下图)。Scope里面多了一个参数-- closure,里面有个num变量。
意思是:fn是一个闭包(待确认,感觉与解释不对应。老师确实说的是,被访问的变量所在的函数是闭包函数)。可以访问fn函数作用域里的num这个变量。
在这里插入图片描述

5.3 闭包的作用

闭包的主要作用:延伸了变量的作用范围。
△ num变量不会等函数执行完毕就销毁,只有等所有的函数都执行完了才销毁。
△ fn外面的作用域可以访问fn内部的局部变量。

便于理解的写法:

  <script>
    // 使 fn外面的作用域可以访问fn内部的局部变量
    function fn() {
      var num = 10;
      // fun()函数可以访问fn函数作用域中的局部变量的num
      function fun() {
        console.log(num);// 10
      }
      return fun;
    }
    
    var f = fn(); // 调用fn():对num进行赋值,并且返回fun,f存储fun()
    // 类似于
    // var f =  function fun() {
    //   console.log(num);
    // }
    
    // f函数一调用就会执行fun函数,因为存的是fun()。
    // fun()函数本身在fn函数中,故可以访问fn函数中的变量。
    f();
  </script>

简易写法 – 将fun函数,写成匿名函数:

  <script>
    // 使 fn外面的作用域可以访问fn内部的局部变量
    function fn() {
      var num = 10;
      // 简易写法:
      return function() {
        console.log(num);// 10
      }
    }
    var f = fn(); // 调用fn(),对num进行复制,并且返回fun,f存储fun()
    // f函数一调用就会执行fun函数,因为存的是fun()。
    // fun()函数本身在fn函数中,故可以访问fn函数中的变量。
    f();
  </script>

5.4 闭包的应用

应用1:点击li输出对应的索引号

  <ul class="nav">
    <li>草莓</li>
    <li>芒果</li>
    <li>香蕉</li>
    <li>火龙果</li>
  </ul>
  <script>
    // 1.之前的做法:利用动态添加属性的方式
    var lis = document.querySelector('.nav').querySelectorAll('li');
    for (var i = 0; i < lis.length; i++) {
      lis[i].index = i;
      lis[i].onclick = function () {
        console.log(this.index);
      }
    }

    // 2.利用闭包循环注册点击事件
    var lis = document.querySelector('.nav').querySelectorAll('li');
    for (var i = 0; i < lis.length; i++) {
      // 利用for循环创建4个立即执行函数
      // 每次循环都会创建一个立即执行函数
      (function(i) {
        lis[i].onclick = function () {
          console.log(i);
        }
      })(i);
    }

  </script>

应用2:循环中的setTimeout()

// 2.利用闭包得到li的索引值
    var lis = document.querySelector('.nav').querySelectorAll('li');
    for (var i = 0; i < lis.length; i++) {
      // 利用for循环创建4个立即执行函数
      // 每次循环都会创建一个立即执行函数
      (function(i) {
        setTimeout(() => {
          // console.log(i);
          console.log(lis[i].innerText);
        }, 3000)
      })(i)
    }

应用3:计算打车价格

  <script>
    //闭包应用-计算打车价格
    //打车起步价13(3公里内),之后每多一公里增加5块钱.用户输入公里数就可以计算打车价格
    //如果有拥堵情况,总价格多收取10块钱拥堵费
    var car = (function() {
      var start = 13;
      var total = 0;
      return {
        price: function(n) {
          if (n <= 3) {
            total = start;
          } else {
            total = start + (n - 3) * 5;
          }
          return total;
        },
        yd: function(flag) {
          return flag ? total + 10 : total;
        }
      }
    })();
    console.log(car.price(5));//23 = 13 + 5 * 2
    console.log(car.yd(true));//33 = total + 10
    
    console.log(car.price(1));//13
    console.log(car.yd(false));// total
  </script>

https://www.bilibili.com/video/BV1Ki4y1T7RF?p=69 待补

6 递归

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值