[TOC]

前言:

完成以下练习

编写代码:计算 1-100 相加并输出结果, 计算 20-80 相加,并输出结果, 计算 100-200 相加,并输出结果

没学函数前, 我们可能会写三遍 for 循环, 有了函数之后只需要写一遍即可.

(一)函数的声明函数的调用

1.1 函数是什么

封装多行语句,可以重复使用,类型为 function

1.2 声明函数和调用函数

<script>
    // 函数声明,实现1道100累加
    function sum() { 
        var sum = 0;
        for(var i=1;i<=100;i++) {
            sum += i;
        }
        console.log(sum);
    }

    // 函数的调用: 函数名+();
    sum();
    sum();
    sum();
    sum(); 

</script>

1.3 函数和变量声明提前

  1. 函数是一等公民, 优先声明

    say();  // 这样写没有错, 函数会先声明
    function say() {
    console.log('hello');
    }
    
  2. 变量是先声明后赋值

    <script>
     console.log(a); // 输出undefined,因为a会先声明, 单不赋值
     var a = 100;
     console.log(a);  // 变量a在这里才赋值, 所有a的值为100;
    </script>
    

    1.4 对象中的函数(方法)

    alert 就是 window 对象的一个方法 ```javascript

    
    <a name="Q7TI5"></a>
    ## 补充知识: 对象和数组
    **(1) 基本数据类型:**
    
       1. 数字
       1. 布尔
       1. undefined
       1. null
       1. 字符串
    
    **(2) 复杂数据类型(引用数据类型)**
    
       6. 对象
       6. 数组
       6. function
    ```javascript
    // 数组
    <script>
        // 1.声明一个数组,第一个成员的下标为0
        var list = ['a','b','c','d'];
        // 2.访问数组通过下标, 其中第一个成下标为0,其他成员依次类推
        console.log('下标为0的成员',list[0]); // 读取下标为0的成员
    
        // 3.数组的长度
        console.log('数组长度',list.length); // 长度为4
    
        // 4.读取最后一个成员的下标: 长度-1
        var len = list.length;
        var last = list[len-1];  // 长度-1
        console.log(last);
    
        // 5.数组遍历
        for(var i=0;i<list.length;i++) {
            console.log('第'+(i+1)+'成员',list[i]);
        }
    </script>
    
    
    // 对象
    <script>
        // 1.声明对象,对象是无序
        var person = {
            // key(键,属性)  value(值)  => 键值对  
            username: '法外狂徒张三',
            say: function () {
                console.log('我是张三');
            },
            age: 100
        }
        // 2.获取对象属性
        console.log('username', person.username);
        console.log('username', person['username']);
    
        // 3.修改对象的属性
        person.username = 'zhangsan';
        console.log('新的名字', person.username);
    
        // 4.调用对象的方法
        person.say();
    </script>
    

    (3) 基本数据类型和引用数据类型的存储

    1. 基本数据类型存放在栈区
    2. 引用数据类型存放在堆区(它的引用存放在栈区)
    3. 以下是基本数据类型和引用数据类型的存放方式

    image.png

    1. 练习: 说出下面代码运行的结果 ```javascript var a = 100; var b = a; b = 200; console.log(a); // a的值是: 100

    var obj1 = { name: ‘张三’, age: 100 } var obj2 = obj1; obj2.name = ‘李四’;

    console.log(obj1.name); // obj1.name的值是多少 李四

    
    <a name="i4k2S"></a>
    ## (二)函数的调用方式
    <a name="3Xghm"></a>
    #### 2.1 手动调用
    <a name="1NTTr"></a>
    #### 2.2 绑定一个事件来调用
    这里的函数叫: 监听器, 事件句柄
    <a name="WO6gc"></a>
    ###### **一个例子**
    从页面上输入两个加数,绑定事件,加上两个加数相加的结果,并显示在页面上
    
    1. 获取元素节点 
    ```javascript
    document.querySelector('#inp');  //获取id为inp的标签
    
    1. 获取input标签的值

      var $inp = document.querySelector('input'); // 获取input标签
      var value = $inp.value; // 读取input标签的值
      
      <!DOCTYPE html>
      <html lang="en"> 
      <body>
         <input id="num1" type="text">+<input id="num2" type="text"><br/><br/>
         <button id="btn" onclick="add();">计算</button> 
         <input type="text" id="sum">
      
       <script>
           // 获取标签
           var $num1 = document.querySelector('#num1');
           var $num2 = document.querySelector('#num2');
           var $sum = document.querySelector('#sum');
      
           function add() {
               // 获取两个加数的值
               var num1 = $num1.value;
               var num2 = $num2.value;
               var sum = num1*1+num2*1;
               $sum.value = sum;
           }
       </script>
      </body>
      </html>
      

      (三)函数传递参数

    3.1 实参和形参

    <script>
        // num1,num2是形参, 用来接收数据,形参的名字自定义
        function add(num1,num2) {
            var sum = num1+num2;
            console.log('相加结果:',sum);
        }
    
        // 100,200是实参
        add(100,200);
    </script>
    

    3.2 函数参数的类型

    1. 参数是基本数据类型
    2. 参数是引用数据类型
    3. 参数是函数(难) ```javascript

      // 回调函数,函数参数是个函数

      
      <a name="SlFhe"></a>
      ## (四)函数返回值 
      4.1 使用 return 返回计算的结果<br />4.2 没写 return, 默认返回undefined<br />4.3 alert(), console.log(); 调用结束后为什么有个"undefined"出现<br />4.4 return 之后的代码不执行
      
      ```javascript
      <script>
        // 1.函数返回值,使用return把运算结果返回给调用者
          function add(a,b) {        
              var sum = a+b;
              return sum;
          }
      
              // result的值是函数里return后面跟着的数据
          var result = add(10,20);
          console.log('result',result);
      </script>
      
      
      // 不写return,默认返回undefined
      function test() {
      
      }
      test(); // 返回undefined
      
      
      <script>
        // return之后的代码不执行
          function add(a,b) {        
              var sum = a+b;
              return sum;
              console.log(1);
              console.log(2);
          }
      
          var result = add(10,20); 
      </script>
      

      (五)作用域

      5.1 什么是作用域

      5.2 全局作用域和全局变量

      1. 全局执行环境(全局作用域): window
      2. 全局变量: 在全局作用域下声明的变量

        5.3 局部作用域和局部变量

      3. 局部执行环境(局部作用域): 函数内部就局部作用域

      4. 局部变量:
        1. 声明在函数内部的变量是局部变量
        2. 局部变量在函数执行的时候存在, 执行结束被销毁
      5. 声明对象不写var,也是全局变量(不推荐)

        5.4 作用域访问规则

      6. 函数内部可以访问函数外部的变量

      7. 函数外部不可以访问函数内部的变量
      8. 作用域链
      9. 没有块级作用域
      <script>
        // 规则1和规则2
          var username = '张三';
          function say() {
              var age = 100;
              console.log(username);
          }
      
          say();
          console.log(age);  // 会报错, 函数外部无法访问函数内部变量
      </script>
      
      
      // 作用域链
      <script>
          // var username = '张三';
          function say() {
              // var username = '李四';
              function say2() {
                  // var username = '老王'; 
                  console.log(username);
              }
              say2();
          }
          say();
      </script>
      
      
      // 没有块级作用域
      <script>
          {
              var a = 100;
          }
          console.log(a); // a不是在函数里声明, 所以它是全局变量
      
          for(var i=0;i<3;i++) {  
              // todo
          }
          console.log(i);  // 3 i不是在函数里声明, 所以它是全局变量
      </script>
      

      作业1:
      编写代码:计算 1-100 相加并输出结果, 计算 20-80 相加,并输出结果, 计算 100-200 相加,并输出结果

      作业2:
      编写一个简单的计算器

      1. 自己设计界面
      2. eval可以执行代码
        var str = '1+2+3';
        var sum = eval(str); // 6
        

      计算器.html

      <!DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta http-equiv="X-UA-Compatible" content="IE=edge">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>Document</title>
          <link rel="stylesheet" href="./style.css">
          <style>
              * { margin: 0; padding: 0; }
              ul,
              li {
                  list-style: none;
              }
          </style>
      </head>
      
      <body>
          <div class="box">
      
              <div class="inp-box">
                  <input id="inp" class="inp" type="text" placeholder="简单计算器">
              </div>
              <ul class="list">
                  <li>C</li>
                  <li>CE</li>
                  <li onclick="add('%',true)">%</li>
                  <li onclick="add('/',true)">/</li>
                  <li onclick="add(7)">7</li>
                  <li onclick="add(8)">8</li>
                  <li onclick="add(9)">9</li>
                  <li onclick="add('*',true)">x</li>
      
                  <li onclick="add(4)">4</li>
                  <li onclick="add(5)">5</li>
                  <li onclick="add(6)">6</li>
                  <li onclick="add('-',true)">-</li>
                  <li onclick="add(1)">1</li>
                  <li onclick="add(2)">2</li>
                  <li onclick="add(3)">3</li>
                  <li onclick="add('+',true)">+</li>
      
                  <li onclick="add(0)" style="width: 210px;">0</li>
                  <li onclick="add('.',true)">.</li>
                  <li>=</li>
              </ul>
          </div> 
      
          <script src="demo.js"></script>
      </body>
      </html>
      

      style.css 代码

      .box {
        margin-top: 100px;
        width: 440px;
        background-color: #ebebeb;
        margin: 0 auto;
        padding: 5px;
      }
      .inp-box {
        height: 50px;
        display: flex;
        justify-content: center;
        align-items: center;
        margin-bottom: 5px;
      }
      .inp-box .inp {
        width: 100%;
        height: 45px;
        border: none;
        text-indent: 20px;
        font-size: 25px;
        outline: none;
      }
      .list {
        display: flex;
        flex-wrap: wrap;
        justify-content: space-between;
      }
      .list li {
        user-select: none;
        width: 100px;
        height: 65px;
        text-align: center;
        line-height: 65px;
        font-size: 20px;
        background-color: #fff;
        margin-bottom: 10px;
        cursor: pointer;
      }
      

      demo.js 代码

      /**
       * 第一个功能
       * 点击数字或者运算符,输入框显示
       */
      
      // 1.1 绑定点击事件
      // 1.2 数字上屏
      
      // 获取输入框对象
      var $inp = document.querySelector("#inp");
      // str用来存放我们点击的数字或者运算符
      var str = '';
      /**
       * @param {*} num 点击的数字或者运算符
       * @param {*} flag 值为true,说明点击的是运算符
       */
      function add(num,flag) { 
          // 输入框的值为空, 并且点击的运算符,就不往下执行
          if(!str && flag) {
             return false;
          }
          // if(str==='' && flag===true) {
          //    return false;
          // }
      
          // last表示str字符最后一个字符
          var last = str[str.length-1];
          // last转换为数字之后,值为NaN,说明last不是数字
          // 如果值不是数字, boo为true, 否则为false
          var boo = isNaN(Number(last));
          // 当前面一个字符是运算符,再点击运算符也不往下执行
          if(flag && boo ) {
              return false;
          }
          // 拼接字符串
          str += num;
        // 把str显示在输入框
        $inp.value = str;
      }
      
      
      // 功能2: 清零
      function clearData() {
          // 将输入的值置空
          $inp.value = '';
          // 将str的值,变为空,不然的话再点击数字的时候, 会跟原来的值拼接在一起
          str = '';
      }
      
      
      // 功能3:计算
      function compute() {
          // last表示str字符最后一个字符
          var last = str[str.length-1];
          // 判断最后一个字符是不是数字
          var boo = isNaN(Number(last));
          if(boo) {
              alert('式子不正确, 检查');
              return false;
          }
      
          // 使用eval计算式子的值
          var result = eval(str);
          // 把结果显示在输入框
          $inp.value = result;
          // 把str的值置空,不然前面式子会一起拼接
          str = '';
      }