前端之JS篇(五)——数组&函数&作用域

1.数组

1.1数组的概念

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vp9nRW2t-1663486690563)(Typora_image/150.png)]

1.2 数组的创建方式

Js创建数组有两种方式:

  1. 利用new创建数据
  2. 利用数组字面量创建数组

1.2.1 利用new 创建数组

var 数组名  = new Array();
var arr = new Array();    // 创建了一个新的空数组,注意Array(),A要大写

1.2.2 利用数组字面量创建数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lPHIUGaw-1663486690565)(Typora_image/151.png)]

var arr = [];   // 创建了一个空数组
var arr1 = [1,2,3,'字符串型',true]; 

1.2.3 数组元素的类型

数组中可以存放任意类型的数据,例如字符串,数字,布尔值等

var arr1 = [1,2,3,'字符串型',true]; 

总结

数组的作用把多个数据存放在一起
数组的创建方式1.利用new创建 2.利用数组字面量创建(常用)
数组元素?数组里面类型有限制吗?存放在数组里面的数据称为数组元素;无限制

1.3 获取数组元素

1.3.1 数组的索引

索引(下标):用来访问数组元素的序号(数组下标从0开始)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yQXbmSlp-1663486690566)(Typora_image/152.png)]

新建.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>
    <script>
        // 1.数组(Array) : 就是一组数据的集合, 存储在单个变量下的优雅方式
        // 2.利用new创建数组
        var arr = new Array();      // 创建了一个空数组
        // 3.利用数组字面量创建数组  []
        var arr = [];   // 创建了一个空数组
        var arr1 = [1,2,3,'字符串型',true]; 
        // 4.数组里面的数据一定用逗号分隔
        // 5. 数组里面的数据 比如1,2 我们称为数组元素
        // 6. 获取数组元素  格式  数组名[索引号]
        console.log(arr1);     // 获取数组arr1里面的全部元素
        console.log(arr1[3]);  // 获取数组arr1索引为3的元素   字符串型
        console.log(arr1[4]);    // true
        console.log(arr1[5]);   // 因为没有这个数组元素  所以输出的结果是 undefined

    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5XxYzdAO-1663486690567)(Typora_image/153.png)]

1.4 遍历数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iXUirqNb-1663486690568)(Typora_image/154.png)]

遍历:就是把数组中每个元素从头到尾都访问一遍(类似我们每天早上学生的点名)

新建.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>
    <script>
        // 遍历数组:就是把数组的元素从头到尾访问一次
        var arr = ['red','green','blue'];
        for (var i = 0; i < 3; i++) {
            console.log(arr[i]);
        }
        /* 
        注意:
        1.因为我们的数组索引号从0开始,所以i必须从0开始 i < 3
        2.输出的时候  arr[i]  i 计数器当索引号来用
        */
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-su45NVhd-1663486690569)(Typora_image/155.png)]

1.5 数组的长度

使用"数组名.length"可以访问数组元素的数量(数组长度)。

新建.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>
    <script>
        // 数组长度
        var arr = [1,2,3,4,5,6,7,8,9,10];
        for (var i =0; i < 10; i++) {
            console.log(arr[i]);
        }
        //  优化版
        console.log(arr.length);
        console.log('***************');
        var arr = [1,2,3,4,5,6,7,8,9,10];
        for (var i =0; i < arr.length; i++) {
            console.log(arr[i]);
        }
        // 1.数组的长度是元素个数  不用跟索引号混淆
        // 2.arr.length 动态检测数组元素的个数
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8eIjfHYy-1663486690571)(Typora_image/156.png)]

总结:

什么是遍历把数组元素从头到尾访问一次
通过什么来遍历数组里面的元素for循环
for 里面的i是什么?当什么使用?for里面的数组元素怎么写?i是计数器,当索引号使用,arr[i]是数组元素 第i个数组元素
如何获取数组的长度arr.length
数组索引号和数组长度有什么关系?索引号从0开始,数组长度是元素个数

1.5.1案例:数组求和及平均值

求数组[2,6,1,7,4] 里面所有元素的和以及平均值。

新建.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>
    <script>
        /* 
        案例分析
        1.声明一个求和变量 sum
        2.遍历这个数组,把里面每个数组元素加到sum里面
        3.用求和变量sum除以数组的长度就可以得到数组的平均值
        */
       var arr = [2,6,1,7,4];
       var sum = 0;
       var average = 0;
       for (var i = 0; i < arr.length; i++) {
        sum += arr[i]   // 此处加的是数组元素arr[i],不是计数器i
       }
       average = sum / arr.length;
       console.log('所有元素的和:'+sum);
       console.log('平均值为:'+ average);
    //    想要输出多个变量,用逗号分隔即可
    console.log(sum,average);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gAFVJO0O-1663486690572)(Typora_image/157.png)]

1.5.2 案例:数组最大值

求数组[2,6,1,77,52,25,7]中的最大值。

<!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>
    <script>
        /* 
        案例分析:
        1.声明一个保存最大元素的变量max
        2.默认最大值可以取数组中的第一个元素
        3.遍历这个数组,把里面每个数组元素和max相比较。
        4.如果这个数组元素大于max就把这个数组元素存到max里面,否则继续下一轮比较。
        5.最后输出这个max
        */
       var arr = [2,6,1,77,52,25,7];
       var max = arr[0];
       for (var i = 1; i < arr.length; i++) {
            if (arr[i] > max) {
                max = arr[i];
            }
       }
       console.log('该数组的最大值为:'+ max);
    //    同理,拓展求最小值

       var min = arr[0];
       for (var i =1; i < arr.length; i++) {
        if (arr[i] < min) {
            min = arr[i];
        }
       }
       console.log('该数组的最小值为:'+ min);
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oGpcTp3I-1663486690573)(Typora_image/158.png)]

1.5.3 案例:数组转换为分割字符串

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0MGxlVaQ-1663486690575)(Typora_image/159.png)]

新建.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>
    <script>
        var arr = ['red','green','blue','pink'];
        var str = '';
        var sep = '|';
        for ( var i = 0; i < arr.length;i++) {
            str += arr[i] + sep;

        }
        console.log(str);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHYBZTjv-1663486690576)(Typora_image/160.png)]

1.6 数组中新增元素

可以通过修改length长度以及索引号增加数组元素

1.6.1 通过修改length长度新增数组元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-o9ujuDUk-1663486690578)(Typora_image/161.png)]

1.6.2 通过修改数组索引新增数组元素

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uk9yMcDv-1663486690579)(Typora_image/162.png)]

新建.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>
    <script>
        // 1. 新增数组元素 修改length长度
        var arr = ['red','green','blue'];
        console.log(arr.length);
        arr.length = 5;    // 把我们数组的长度修改为了5,里面应该有五个元素
        console.log(arr);   // (5) ['red', 'green', 'blue', empty × 2]
        console.log(arr[3]);  // undefined
        console.log(arr[4]);  // undefined
        arr.length = 2;
        console.log(arr);   // (2) ['red', 'green']
        arr.length = 3;    // (3) ['red', 'green', empty]
        console.log(arr);

        // 新增数组元素  修改索引号
        var arr1 = ['red','green','blue'];
        arr1[3] = 'yellow';
        console.log(arr1);  // (4) ['red', 'green', 'blue', 'yellow']
        arr1[4] = 'orange';
        console.log(arr1);  // (5) ['red', 'green', 'blue', 'yellow', 'orange']
        // 如果位置被占用,替换原来的数组元素
        arr1[2] = 'blank';
        console.log(arr1);   // (5) ['red', 'green', 'blank', 'yellow', 'orange'] 
        // 特别注意: 不要给数组名直接赋值,否则会覆盖掉以前的数据
        arr1 = '你好'
        console.log(arr1);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JMDcPj2D-1663486690582)(Typora_image/163.png)]

1.6.3 案例 :数组新增元素

新建一个数组,里面存放100个整数(1~100)

案例分析:

1.使用循环来追加数组

2.声明一个空数组arr

3.循环中的计数器i可以作为数组元素存入

4.由于数组的索引号是从0开始的,因此计数器从0开始更合适,存入的数组元素要+1

新建.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>
    <script>
        var arr = [];
        for (var i = 0;i < 100; i++) {
            // arr = i; 不要直接给数组名赋值  否则以前的元素都没了
            arr[i] = i + 1;
        }
        console.log(arr);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJ23bzHF-1663486690584)(Typora_image/164.png)]

1.6.4 案例:筛选数组

要求:将数组[2,0,6,1,77,0,52,0,25,7]中大于等于10的元素选出来,放入新数组。

案例分析

1.声明一个新数组用于存放新数据newArr

2.遍历原来的旧数组,找出大于等于10的元素

3.依次追加给新数组newArr

新建.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>
    <script>
        // 方法一
       /*  var arr = [2,0,6,1,77,0,52,0,25,7];
        var newArr = [];
        var j = 0;
        for (var i = 0;i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[j] = arr[i]
                j++;
            }
        }
        console.log(newArr); */
        // 方法二
        var arr = [2,0,6,1,77,0,52,0,25,7];
        var newArr = [];   // 刚开始 newArr.length 就是0
        console.log(newArr.length);   // 0
        for (var i = 0;i < arr.length; i++) {
            if (arr[i] >= 10) {
                // 新数组索引号应该从0开始 依次递增
                newArr[newArr.length] = arr[i]
            }
        }
        console.log(newArr);
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fi9RsDCP-1663486690585)(Typora_image/165.png)]

1.7 数组案例

1.7.1 案例:删除指定数组元素(数组去重)

要求:将数组[2,0,6,1,77,0,52,0,25,7]的0去掉后,形成一个不包含0的新数组。

案例分析

1.需要一个新数组用于存放筛选之后的数据

2.遍历原来的数组,把不是0的数据添加到新数组里面(此时要注意采用数组名+索引的格式接收数据)。

3.新数组里面的个数,用length不断累加

新建.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>
    <script>
        var arr = [2,0,6,1,77,0,52,0,25,7];
        var newArr = [];
        for (var i = 0; i < arr.length;i++) {
            if (arr[i] != 0) {
                newArr[newArr.length] = arr[i];
            }
        }
        console.log(newArr);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qaljZWSH-1663486690592)(Typora_image/166.png)]

1.7.2 案例:翻转数组

要求:将数组[‘red’,‘green’,‘blue’,‘pink’,‘purple’]的内容反过来存放。

输出: [‘purple’,‘pink’,‘blue’,‘green’,‘red’]

分析

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JanB3Rc3-1663486690594)(Typora_image/167.png)]

案例分析

1.声明一个新数组newArr

2.把旧数组索引号第4个取过来(arr.length - 1) ,给新数组索引号第0 个元素(newArr.length)

3.采用递减的方式 i–

新建.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>
    <script>
        var arr = ['red','green','blue','pink','purple'];
        var newArr = [];
        for (var i = arr.length -1; i >= 0;i--) {
            newArr[newArr.length] = arr[i]; 
        }
        console.log(newArr);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QXrTP0la-1663486690597)(Typora_image/168.png)]

1.7.3 案例: 数组排序(冒泡排序)

冒泡排序:是一种算法,把一系列的数据按照一定的顺序进行排列显示(从小到大或者从大到小)。

例如:我们可以将数组[5,4,3,2,1]中的元素按照从小到大的顺序排序,输出:1 ,2 ,3 ,4 ,5 。反之亦可。

冒泡排序是一种简单的排序算法。它重复走访过要排序的数列 ,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。

回顾之前交换变量代码,如下

<!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>
    <script>
        // 交换两个变量
        var num1 =  '1号位';
        var num2 = '2号位';
        var temp;
        temp = num1;
        num1 = num2;
        num2 = temp;
        console.log(num1,num2);
    </script>
</head>
<body>
    
</body>
</html>

分析原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7wkakOfB-1663486690598)(Typora_image/170.png)]

新建.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>
    <script>
        // 冒泡排序
        // var arr = [4,1,2,3,5]
        var arr = [5,4,3,2,1]
        for (var i = 0; i <= arr.length - 1;i++) {         // 外层循环管趟数
            for (var j = 0; j <= arr.length -i - 1;j++) {   // 里层循环管每一趟的交换次数
                // 内部交换两个变量的值  前一个和后一个数组元素相比较
                if (arr[j] > arr[j + 1]) {
                    var temp = arr[j];
                    arr[j] = arr[j + 1];
                    arr[j+1] = temp;
                }
            }
        }
        console.log(arr);
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-863wYso6-1663486690601)(Typora_image/169.png)]

2. 函数

2.1 函数的概念

在JS里面,可能会定义非常多的相同代码或者功能相似的代码,这些代码可能需要大量重复使用。

虽然for循环语句也能实现一些简单的重复操作,但是比较具有局限性,此时我们就可以使用JS中的函数。

函数:就是封装了一段可被重复调用执行的代码块。通过此代码可以实现大量代码的重复使用。

新建.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>
    <script>
        // 1.求1~100的累加和
        var sum = 0;
        for (var i = 1; i <= 100; i++) {
            sum += i;
        }
        console.log(sum);      // 5050

        // 2. 求1~50的累加和
        var sum = 0;
        for (var i = 1; i <= 50;i++) {
            sum += i
        }
        console.log(sum);    // 1275

        // 3. 函数的方法做上面的计算
        // 函数就是封装了一段可以被重复执行调用的代码块,目的:让大量代码重复使用
        function getSum(num1,num2) {
            var sum = 0;
            for (var i = num1;i <= num2;i++) {
                sum += i
            }
            console.log(sum);
        }
        getSum(1,100)   // 5050
        getSum(1,50)    // 1275
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8OrX0Uy-1663486690602)(Typora_image/171.png)]

2.2 函数的使用

函数在使用时分为两步:声明函数和调用函数。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PGSGkHnv-1663486690604)(Typora_image/172.png)]

新建.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>
    <script>
        // 函数使用分为两步:声明函数和调用函数
        // 1.声明函数
        function 函数名() {
            // 函数体
        }
        /* 
        注意:
        (1) function 是声明函数的关键字,全部小写
        (2) 函数是做某件事情,函数名一般是动词 例如:sayHello
        (3) 函数不调用自己不执行  
        */

        // 2.调用函数
        //  函数名();

        function sayHello() {
            console.log('今天你好吗?');
        }
        sayHello();
        // 调用函数的时候千万不要忘记加小括号
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-H8ycUgFb-1663486690606)(Typora_image/173.png)]

2.2.1 函数的封装

函数的封装是把一个或者多个功能通过函数的方式封装起来,对外只提供一个简单的函数接口。

简单理解:封装类似于将电脑配件整合组装到机箱中(类似于快递打包)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GYS3ghIe-1663486690607)(Typora_image/174.png)]

2.2.2 函数封装案例:计算1~100之间的累加和

新建.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>
    <script>
        // 利用函数计算1~100之间的累加和
        // 1.声明函数
        function getSum(num1,num2) {
            var sum = 0;
            for (var i = num1; i <= num2;i++) {
                sum += i;
            }
            console.log(sum);
        }
        // 2.调用函数
        getSum(1,100);     // 5050

        // 计算55~100之间的累加和
        getSum(55,100)    // 3565
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ub588kYK-1663486690610)(Typora_image/175.png)]

小结

函数的作用大量代码重复使用(封装了一段可以被重复执行的代码块)
声明函数的关键字function
如何调用函数函数名();
封装什么意思打包

2.3 函数的参数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gnVNK8jq-1663486690612)(Typora_image/176.png)]

新建.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>
    <script>
        // 1.函数可以重复相同的代码
        function cook() {
            console.log('酸辣土豆丝');
        }
        cook();   // 酸辣土豆丝
        cook();   // 酸辣土豆丝
        // 2.可以利用函数实现函数重复不同的代码
        /*  
        function 函数名(形参1,形参2...) {         
            函数体
        }
        函数名(实参1,实参2...);

        形参:在声明函数的小括号里面是  形参  (形式上的参数)
        实参:在函数调用的小括号里面是实参  (实际的参数)
        parameter 形参    argument 实参
        */
        // 3.形参和实参的执行过程
        function cook_one(para) {     //  形参是接收实参的,相当于一个变量  para = '鱼香肉丝'
            console.log(para); 
        }
       cook_one('鱼香肉丝')  // 鱼香肉丝
       cook_one('韭菜鸡蛋')  // 韭菜鸡蛋
        // 4.函数的参数可以有,也可以没有个数不限

    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HCJxIH2i-1663486690613)(Typora_image/177.png)]

2.3.1 案例演示

新建.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>
    <script>
        // 1.利用函数求任意两个数的和
        function numSum(num1,num2) {
            var sum = 0;
            sum = num1 + num2;
            console.log(sum);
        }
        
        // 2.求1和8的和
        numSum(1,8);   // 9
        // 2.利用函数求任意两个数之间的和
        function getSum(num1,num2) {
            var totle = 0
            for (var i = num1; i <= num2; i++) {
                totle += i;
            }
            console.log(totle);
        }
        // 求1和8之间的和
        getSum(1,8)   // 36

        /* 
        3. 注意点:
        (1) 多个参数之间用逗号隔开
        (2) 形参可以看做是不用声明的变量
        */
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hQzhkwr1-1663486690615)(Typora_image/178.png)]

2.3.2 函数形参和实参个数不匹配问题

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OOhU4th3-1663486690616)(Typora_image/179.png)]

新建.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>
    <script>
        // 函数形参实参个数匹配
        function getSum(num1,num2) {
            console.log(num1 + num2);
        }
        // 1.如果实参的个数和形参的个数一致,则正常输出结果
        getSum(1,2);   // 3
        // 2.如果实参的个数多于形参的个数,会取到形参的个数
        getSum(1,2,3,4)   // 3
        getSum(1,8,9)     // 9
        // 3.如果实参的个数小于形参的个数,多于的形参定义为undefined  最终的结果就是NaN
        getSum(1)   // NaN
        getSum()    // NaN
        // 建议:我们尽量让实参的个数和形参相匹配
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-X9MlIg8B-1663486690618)(Typora_image/180.png)]

小结

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZVtV1K0z-1663486690620)(Typora_image/181.png)]

2.4 函数的返回值

2.4.1 return语句

有时候,我们会希望函数将返回值返回给调用者,此时通过return语句既可以实现。

新建.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>
    <script>
        // 1.函数是做某件事或者实现某种功能
        function cook(aru) {
            console.log(aru);
        }
        console.log('鱼香肉丝');    // 鱼香肉丝
        // 2.函数的返回值格式
        /*  
        function 函数名() {
            return 需要返回的结果;
        }
        函数名();
        
        注意点:
        (1) 函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名(), 通过return 实现的
        (2) 只是函数遇到return 就把后面的结果 返回给函数的调用者   函数名() = return后面的结果
        */
        // 3.代码验证
        function getResult() {
            return '哈喽,你好吗';
        }
        getResult();      // 相当于做了 getResult() = '哈喽,你好吗'
        console.log(getResult());  // 哈喽,你好吗

        // 完善最前面代码
        function cookOne(aru) {
            return aru;
        }
        console.log(cookOne('水煮肉片'));   // 水煮肉片

        // 优化代码:求两个数的和
        function getSum(num1,num2) {
            return num1 + num2;

        }
        console.log(getSum(5,19));   // 24
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pzKUg0U0-1663486690622)(Typora_image/182.png)]

2.4.2 案例:利用函数求任意两个数的最大值

新建.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>
    <script>
        // 利用函数,求两个数的最大值
        function getMax(num1,num2) {
            if (num1 > num2) {
                return num1;
            } else {
                return num2;
            }
        }

        // 反之求最小值
        function getMin(num1,num2) {
            if (num1 > num2) {
                return num2;
            } else {
                return num1;
            }
        }

        // 求28和35的最大值,最小值
        getMax(28,35);
        console.log( getMax(28,35));   // 35
        getMin(28,35);
        console.log(getMin(28,35));    // 28

        // 用三元表达式进行优化
        function getMax1(num1,num2) {
            return num1 > num2 ? num1 : num2;
        }

        function getMin1(num1,num2) {
            return num1 > num2 ? num2 : num1;
        }

        console.log( getMax1(18,69));   // 69
        console.log( getMin1(32,41));   // 32
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Qbrk4RYN-1663486690624)(Typora_image/183.png)]

2.4.3 案例:利用函数求任意一个数组中的最大值

利用函数求数组[5,2,99,101,67,77]中的最大数值

新建.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>
    <script>
        // 利用函数求数组 [5,2,99,101,67,77]中的最大数值
        function getArrMax(arr) {     // arr 接收一个数值
            var max = arr[0];
            for (var i = 1; i <= arr.length; i++) {
                if (arr[i] > max) {
                    max = arr[i];
                }
            }
            return max;
        }
        // getArrMax([5,2,99,101,67,77])    // 实参是一个数组送过去
        // 在实际开发里面,我们经常用一个变量来接收  函数的返回结果,使用更简单
        var re = getArrMax([5,2,99,101,67,77]);
        console.log(re);     // 101

        // 任意一个数组也可以求最值
        var msg = getArrMax([3,6,12,6,88,199,5,2])
        console.log(msg);   // 199 
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QEsjpYHY-1663486690625)(Typora_image/184.png)]

2.4.4 return 终止函数

return语句之后的代码不被执行

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LrNVlZfZ-1663486690628)(Typora_image/185.png)]

2.4.5 return 的返回值

return 只能返回一个值。如果用逗号隔开多个值,以最后一个为准。(返回多个值的话可以用数组方式来实现)

2.4.6 函数没有 return 返回undefined

函数都是有返回值的

1.如果有return 则返回return后面的值

2.如果没有return 则返回undefined

新建.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>
    <script>
        // 函数返回值注意事项
        // 1. return  终止函数
        function getSum(num1,num2) {
            return num1 + num2;  // return 后面的代码不会被执行
            alert('我是不会被执行的');
        }
        console.log(getSum(1,2));

        // 2. return 只能返回一个值
        function fn(num1,num2) {
            return num1,num2;     // 返回的结果是最后一个值
        }
        console.log(fn(1,2));

        // 3.我们求任意两个数的加减乘除的结果
        function getResult(num1,num2) {
            return [num1 + num2, num1 - num2, num1 * num2, num1 / num2];
        }
        var re = getResult(8,4);    // 返回的是一个数组
        console.log(re);         // [12, 4, 32, 2]

        // 4.我们的函数如果有return 则返回的是return 后面的值,如果函数没有return 则返回undefined
        function fun1() {
            return 666;
        }
        console.log(fun1());   // 返回 666

        function fun2() {
            
        }
        console.log(fun2());  // 返回 undefined

    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-besVJB2u-1663486690632)(Typora_image/186.png)]

2.4.7 break,continue,return的区别

break结束当前的循环体(如for、while)
continue跳出本次循环,继续执行下次循环(如for、while)
return不仅可以退出循环,还能够返回return语句中的值,同时还可以结束当前的函数体内的代码

2.5 通过榨汁机看透函数

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GJ4kvW2e-1663486690634)(Typora_image/187.png)]

2.5.1 小结案例

新建.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>
    <script>
        // 1.写一个函数,用户输入任意两个数字的任意算术运算(简单的计算器小功能),并能弹出运算后的结果
        function getResult1(operator,num1,num2) {
            var operator = prompt("请输入您的运算符('+','-','*','/')");
            var num1 = prompt('请输入您的第一个数字');
            var num2 = prompt('请输入您的第二个数字');
            if (operator == '+') {
                return parseFloat(num1) + parseFloat(num2)           
            } else if (operator == '-') {
                return num1 - num2

            } else if (operator == '*') {
                return num1 * num2
                
            } else if (operator == '/') {
                return num1 / num2
                
            } else {
                return '运算符错误';
            }
        }
        alert(getResult1());
        // 2.写一个函数,用户输入任意两个数字的最大值,并能出弹运算后的结果
            function getMax(num1,num2) {
                var num1 = parseInt(prompt('请输入数字'));
                var num2 = parseInt(prompt('请输入数字'));
                return num1 > num2 ? num1 : num2;
            }
            alert(getMax())
        // 3. 写一个函数,用户输入任意三个不同数字的最大值,并能弹出运算后的结果
            var num1 = parseInt(prompt('输入第一个数字'));
            var num2 = parseInt(prompt('输入第二个数字'));
            var num3 = parseInt(prompt('输入第三个数字'));
            var arr = [num1,num2,num3]
            var max = num1;
            function getMaxValue(num1,num2,num3) {
                
                for (var i = 1; i < arr.length; i++) {
                    if (arr[i] > max) {
                        max = arr[i];
                    } 
                }
                return max;
            }
            alert(getMaxValue())
        // 4.写一个函数,用户输入一个数判断是否是素数,并返弹出回值(又叫质数,只能被1和自身整除的数)
            function judgePrime(num1) {
                var num1 = parseFloat(prompt('请输入数字'));
                for (var i= 2; i < num1;i++) {
                    if (num1 % i == 0) {
                        return num1 + '不是质数';
                    }
                }
                return num1 + '是质数';
            }
            alert(judgePrime())
    </script>
</head>
<body>
    
</body>
</html>

2.6 arguments的使用

当我们不确定有多少个参数传递的时候,可以用arguments来获取。在JavaScript中,arguments实际上它是当前函数的一个内置对象。所有函数都内置了一个arguments对象,arguments对象中存储了传递的所有实参。

arguments展示形式是一个伪数组,因此可以进行遍历。伪数组具有以下特点:

1.具有length属性

2.安索引方式储存数据

3.不具有数组的push,pop等方式

新建.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>
    <script>
        // arguments 的使用
        // 只有函数才有arguments对象,而且是每个函数都内置好了这个arguments
        function fn() {
            console.log(arguments);      // 里面存储了所有传递过来的实参
            console.log(arguments.length);  // 3
            console.log(arguments[2]);      // 3
            // 可以按照数组的方式遍历arguments
            for (var i = 0; i < arguments.length;i++) {
                console.log(arguments[i]);
            }
        }
        fn(1,2,3);
        fn(1,2,3,4,5,6,7)

        /* 
        注意:
        1. 伪数组  并不是真正意义上的数组
        2. 按照索引的方式进行存储的
        3. 它没有真正数组的一些方式  pop()  push()  等等
        
        
        */
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evxuznGm-1663486690638)(Typora_image/188.png)]

2.6.1 案例:利用函数求任意个数的最大值

新建.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>
    <script>
        // 利用函数求任意个数的最大值
        function getMax() {      // 相当于 arguments = [1,2,3]
            var max = arguments[0];
            for (var i = 1; i < arguments.length;i++) {
                if (arguments[i] > max) {
                    max = arguments[i];
                }
            }
            return max;
        }
        console.log(getMax(1,2,3));
        console.log(getMax(12,43,546,7575,435,3));
        console.log(getMax(12,65,76,23,7,2,34));
        console.log(getMax(4,5,7,4,2,6,1));
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aYGDpaKG-1663486690639)(Typora_image/189.png)]

2.7 函数案例

2.7.1 案例:利用函数封装方式,翻转任意一个数组

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-j6oRsaUr-1663486690647)(Typora_image/167.png)]

新建.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>
    <script>
        // 利用函数翻转任意数组  reverse 翻转
        function reverse(arr) {
            var newArr = [];
            for (var i = arr.length - 1; i >= 0;i--) {
                newArr[newArr.length] =  arr[i];
            }
            return newArr;
        }
        var arr1 = reverse([1,3,5,7,9,11]);
        console.log(arr1);                     // [11, 9, 7, 5, 3, 1]
        var arr2 = reverse(['red','pink','blue']);
        console.log(arr2);                     // ['blue', 'pink', 'red']
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-M5O42jWv-1663486690650)(Typora_image/190.png)]

2.7.3 案例:利用函数封装的方式,对数组排序—冒泡排序

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hhbTEid1-1663486690653)(Typora_image/170.png)]

新建.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>
    <script>
        // 利用函数冒泡排序
        function sort(arr) {
            for (var i = 0; i < arr.length - 1; i++) {
                for (var j =0; j < arr.length -i -1;j++) {
                    if (arr[j] > arr[j + 1]) {
                        var temp = arr[j];
                        arr[j] =arr[j+1];
                        arr[j+1] = temp; 
                    }
                }
            }
            return arr;
        }
        var arr1 = sort([1,4,3,2,9]);
        console.log(arr1);              // [1, 2, 3, 4, 9]
        var arr2 = sort([1,44,68,23,5,99,3]);
        console.log(arr2);             //  [1, 3, 5, 23, 44, 68, 99]

    </script>
</head>
<body>
    
</body>
</html>

Python的冒泡写法

def sort(items):
      for i in range(len(items) - 1):
          for j in range(len(items) - 1 - i):
              if items[j] > items[j + 1]:
                  items[j], items[j + 1] = items[j + 1], items[j]
    return items

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8ffH2lqK-1663486690653)(Typora_image/191.png)]

2.7.4 案例:利用函数判断闰年

要求:输入一个年份,判断是否是闰年(闰年:能被4整除并且不能被100整除,或者能被400整除)

新建.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>
    <script>
        // 利用函数判断闰年
        function isRunYear(year) {
            // 如果是闰年,返回true,否则,返回false
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
        console.log(isRunYear(2000));   // true
        console.log(isRunYear(2014));   // false
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lclMffYz-1663486690655)(Typora_image/192.png)]

2.7.5 案例:函数可以调用另外一个函数

因为每个函数都是独立的代码块,用于完成特殊任务,因此经常会用到函数相互调用的情况。

新建.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>
    <script>
        // 函数是可以相互调用的
        function fn1() {
            console.log(1111);
            fn2();   // 在fn1函数里面调用了fn2函数
            console.log('fn1');
        }
        fn1();

        function fn2() {
            console.log(2222);
            console.log('fn2');
        }
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3frsdiNf-1663486690658)(Typora_image/193.png)]

2.7.6 案例:用户输入年份,输出当前年2月份的天数

要点:如果是闰年,则2月份是29天,如果是平年,则2月份是28天

新建.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>
    <script>
        // 用户输入年份,输出当前年份2月份的天数
        function backDay() {
            var year = prompt('请你输入年份:');
            if(isRunYear(year)) {           // 调用函数需要加小括号
                alert('当前年份是闰年,2月份有29天');
            } else {
                alert('当前年份是平年,2月份有28天')
            }

        }
        backDay();

         // 利用函数判断闰年
         function isRunYear(year) {
            // 如果是闰年,返回true,否则,返回false
            var flag = false;
            if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
                flag = true;
            }
            return flag;
        }
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7UOY2EY8-1663486690659)(Typora_image/194.png)]

2.8 函数的两种声明方式

新建.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>
    <script>
        // 函数的2种声明方式
        // 1.利用函数关键字自定义函数(命名方式)
        function fn() {
            console.log('fn');
        }
        // 调用方式
        fn();
        // 2. 函数表达式(匿名函数)
        // 方式: var 变量名 = function() {};
        var fun = function() {
            console.log('我是函数表达式');
        }
        fun();
        /* 
        注意:
        1.fun是变量名,不是函数名
        2.函数表达式声明方式跟变量差不多,只不过变量里面存的是值,而函数表达式里面存的是函数
        3.函数表达式也可以进行传递参数
        */
       var color = function(arg) {
        console.log('你需要的颜色');
        console.log(arg);
       }
       color('red')   // 你需要的颜色   红色
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DmRP9eNV-1663486690660)(Typora_image/195.png)]

3.作用域

3.1 作用域的概述

通常来说,一段程序代码中所用到的名字并不总是有效和可用的,而限定这个名字的可用性的代码范围就是这个名字的作用域。作用域的使用提高了程序逻辑的局部性,增强了程序的可靠性,减少了名字的冲突。

新建.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>
    <script>
        /* 
        1.javaScript作用域:就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突
        2.js的作用域(es6版本)之前:全局作用域   局部作用域
        3.全局作用域:整个script标签  或者是一个单独的js文件
        4.局部作用域(函数作用域):在函数内部就是局部作用域,这个代码的名字只在函数内部起效果和作用
        5.全局作用域和局部作用域的相同变量不会发生冲突,同一个作用域下变量一样会冲突
        */
       // 全局作用域
       var num = 10;
       console.log(num);
       function fn() {
        // 局部作用域
        var num = 20;
        console.log(num);
       }
       fn();
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m2ilQhwW-1663486690662)(Typora_image/196.png)]

3.2 变量作用域的分类

在JavaScript中,根据作用域不同,变量可以分为两种:

​ 全局变量

​ 局部变量

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ESUINIWe-1663486690664)(Typora_image/197.png)]

新建.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>
    <script>
        // 变量作用域:根据作用域的不同,变量分为全局变量和局部变量
        // 1.全局变量:
        //      (1) 在全局作用域下的变量  在全局下都可以使用
        //      (2) 在函数的内部  没有声明直接赋值的变量(重点注意)
        var num = 10;     // num就是一个全局变量
        console.log(num);   // 10

        function fn() {
            console.log(num);
        }
        fn();       // 10
        // 2. 局部变量
        //        (1) 在局部作用域下的变量  在函数内部的变量就是局部变量
        //        (2) 函数的形参也可以看作是局部变量(重点注意)
        function fun() {
            var num1 = 10;  // num1就是局部变量,只能在函数内部使用
            name = '张三';       // 这是全部变量,不建议使用
        }
        fun();
        console.log(name);    // '张三'
        console.log(num1);    //   Uncaught ReferenceError: num1 is not defined
        // function fun1(arr) {
        //     var num1 = 10;  // num1就是局部变量,只能在函数内部使用
        //     name = '张三';       // 这是全部变量
        // }
        // fun1();
        // console.log(arr);   // Uncaught ReferenceError: arr is not defined
        /* 
        3.从执行效率来看全局变量和局部变量
            (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存
            (2) 局部变量 当我们程序执行完毕就会销毁,比较节约内存资源
        
        */
    </script>
</head>
<body>
    
</body>
</html>

效果如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-abNOGpxg-1663486690665)(Typora_image/198.png)]

3.3 JavaScript没有块级作用域

ECMAScript 6(简称ES6)是于2015年6月正式发布的JavaScript语言的标准,正式名为ECMAScript 2015(ES2015)。它的目标是使得JavaScript语言可以用来编写复杂的大型应用程序,成为企业级开发语言 。

另外,一些情况下ES6也泛指ES2015及之后的新增特性,虽然之后的版本应当称为ES7、ES8等。

新建.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>
    <script>
        // js中没有块级作用域 js的作用域:全局作用域  局部作用域  现阶段我们js中没有块级作用域
        // js中的块级作用域在es6版本之后新增的块级作用域 
        // 块级作用域  {}

        if (3 < 5) {
            var num = 10;
        }
        console.log(num);  // 10
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-N9h6yh3N-1663486690667)(Typora_image/199.png)]

3.3 作用域链

新建.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>
    <script>
        // 作用域链:内部函数访问外部函数的变量,采用的是链式查找的方法来决定取哪个值,这种结构我们称为作用域链
        //  也就是从内到外,一级一级的查找,就近原则
        var num = 10;
        var year = 2022;
        function fn() {      // 外部函数
            var num = 20;
            function fun() {          // 内部函数
                console.log(num);     // 20
                console.log(year);    // 2022
            }
            fun();
        }
        fn();   
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3VkjXF83-1663486690668)(Typora_image/200.png)]

3.3.1 案例:结果是几?

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UysniWTw-1663486690676)(Typora_image/201.png)]

新建.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>
    <script>
        // 案例1:结果是几?
        function f1() {
            var num = 123;
            function f2() {
                console.log(num);   
            }
            f2();
        }
        var num = 456;
        f1();     // 123
        // 案例2:结果是几?
        var a = 1;
        function fn1() {
            var a = 2;
            var b = '22';
            fn2();
            function fn2() {
                var a = 3;
                fn3();
                function fn3() {
                    var a = 4;
                    console.log(a);      // 4
                    console.log(b);      // '22'
                }
            }
        }
        fn1();

    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LwsE38Jj-1663486690678)(Typora_image/202.png)]

4.JavaScript预解析

JavaScript代码是由浏览器中的JavaScript解析器来执行的。JavaScript解析器在运行JavaScript代码的时候分为两步:预解析和代码执行。

问题背景:

新建.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>
    <script>
        // 问题1:执行结果是什么?
        // console.log(num1);     报错 Uncaught ReferenceError: num1 is not defined
        // 问题2:执行结果是什么?
        console.log(num2);    undefined
        var num2 = 10;
        // 问题3:执行结果什么?
        function fn() {
            console.log('放下面可以调用');
        }
        fn();
        fn1();
        function fn1() {
            console.log('放上面可以调用');
        }
        // 问题4:执行结果是什么?
        var fun = function() {
            console.log('放下面可以调用');
        }
        fun();
        fun1();     // 38-预解析.html:28 Uncaught TypeError: fun1 is not a function
        var fun1  = function() {
            console.log('放上面可以调用吗');
        }


    </script>
</head>
<body>
    
</body>
</html> 

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3GzVMU7b-1663486690679)(Typora_image/203.png)]

基础背景回顾:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IvLolEwz-1663486690680)(Typora_image/031.png)]

上面问题1的报错和问题4的报错是什么原因呢?

新建.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>
    <script>
        // 问题1:执行结果是什么?
        // console.log(num1);     报错 Uncaught ReferenceError: num1 is not defined
        // 问题2:执行结果是什么?
        console.log(num2);    undefined    (此处用变量提升解释)
        var num2 = 10;

        // 第12,13行代码相当于执行了以下代码
        // var num2;
        // console.log(num2);    此时只声明没赋值
        // num2 = 10;



        // 问题3:执行结果什么?
        function fn() {
            console.log('放下面可以调用');
        }
        fn();
        fn1();
        function fn1() {
            console.log('放上面可以调用');
        }
        /* 
        函数提升
        不管调用的时候写上面还是下面,在预解析的时候都会提上面    
        */

        // 问题4:执行结果是什么?
        var fun = function() {
            console.log('放下面可以调用');
        }
        fun();
        fun1();     // 38-预解析.html:28 Uncaught TypeError: fun1 is not a function
        var fun1  = function() {
            console.log('放上面可以调用吗');
        }
        // 第36行,37行,38行,38行代码相当于执行了以下代码
        // var fun1;
        // fun1();      此时只声明没给函数
        // var fun1  = function() {
        //     console.log('放上面可以调用吗');
        // }

       /*  如果调整为:
        var fun1  = function() {
            console.log('放上面可以调用吗');
        }
        fun1(); 
        就可以正常运行 */
        /* 
        知识点:
        1. JS引擎运行js分为两步:预解析  代码执行
           (1) 预解析 js引擎会把js里面所有的var 还有 function提升到当前作用域的最前面
           (2) 代码执行   按照代码书写的顺序从上往下执行
        2.预解析分为变量预解析(变量提升)和 函数预解析 (函数提升)
           (1) 变量提升  就是把所有的变量声明提升到当前的作用域最前面   不提升赋值操作  (问题2,问题4)
           (2) 函数提升  就是把所有的函数声明提升到当前作用域的最前面   不调用函数      (问题3)
        
        总结:
           1.函数表达式调用时,必须写在函数表达式的下面
           2.变量初始化放在打印变量之前
        
        
        */

    </script>
</head>
<body>
    
</body>
</html> 

4.1 预解析案例:结果是几?

案例一,新建.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>
    <script>
        // 案例1
        var num = 10;
        fun();   
        function fun() {
            console.log(num);
            var num = 20;
        }
        /* // 相当于执行了以下操作
        // 1.变量提升
        var num;
        // 2.函数提升
        function fun() {
            console.log(num);
            var num = 20;     // 函数里面的也需要变量提升
        }
        // 3.剩下的依次写
        num = 10;
        fun(); 
        // 4.对函数里面的进行变量提升,这样就成了
        var num;
        function fun() {
            var num;
            console.log();
            num = 20;
        }
        num = 10;
        fun(); */


        // 按照作用域链一级一级执行,所以  本案例执行结果为undefined;

    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s4Jgd6Lf-1663486690684)(Typora_image/204.png)]

案例二,新建.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>
    <script>
        var num =  10;
        function fn() {
            console.log(num);
            var num = 20;
            console.log(num);
        }
        fn();

        // 相当于执行了以下代码
        // var num;
        // function fn() {
        //     var num;
        //     console.log(num);
        //     num = 20;
        //     console.log(num);
        // }
        // num = 10;
        // fn();
        // 所以,根据作用域链的就近原则,结果为: undefined  20
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0LpMcEt6-1663486690706)(Typora_image/205.png)]

案例三,新建.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>
    <script>
        var a = 18;
        f1();
        function f1() {
            var b = 9;
            console.log(a);
            console.log(b);
            var a = '123';
        }
        // 上面代码相当于执行了下面代码
        // var a;
        // function f1() {
        //     var b;
        //     var a;
        //     b = 9;
        //     console.log(a);
        //     console.log(b);
        //     a = '123';
        // }
        // a = 18;
        // f1();
        // 所以 根据作用域链来分析,该段代码返回值为: undefined  9
    </script>
</head>
<body>
    
</body>
</html>

效果如下

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ifrbhBTz-1663486690708)(Typora_image/206.png)]

案例四,新建.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>
    <script>
        f1();
        console.log(c);
        console.log(b);
        console.log(a);
        function f1() {
            var a = b = c = 9;   // 相当于 var a = 9;b =9; c = 9; 
            console.log(a);
            console.log(b);
            console.log(c);
        }
        // 以上代码相当于执行了下面代码
        // function f1() {
        //     var a;
        //     a = 9;
        //     b = 9;        // b和c没有直接赋值  没有var声明,当全局变量看,a在函数里面有var,当局部变量看
        //     c = 9;
        //     console.log(a);
        //     console.log(b);
        //     console.log(c);
        // }
        // f1();
        // console.log(c);
        // console.log(b);
        // console.log(a);
        // 根据作用域的就近原则,其值为 9,9,9,9,9,报错
    </script>
</head>
<body>
    
</body>
</html>

效果如下
在这里插入图片描述

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

今晚务必早点睡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值