day4 js数组 & 函数 & 作用域

    技术2024-12-24  12

    1. 数组

    1.1 创建

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> <script> // 1.数组(Array) :就是一组数据的集合 存储在单个变量下的优雅方式 // 2. 利用new 创建数组 var arr = new Array(); // 创建了一个空的数组 // 3. 利用数组字面量创建数组 [] var arr = []; // 创建了一个空的数组 var arr1 = [1, 2, 'pink老师', true]; // 4. 我们数组里面的数据一定用逗号分隔 // 5. 数组里面的数据 比如1,2, 我们称为数组元素 // 6. 获取数组元素 格式 数组名[索引号] 索引号从 0开始 console.log(arr1); console.log(arr1[2]); // pink老师 console.log(arr1[3]); // true var arr2 = ['迪丽热巴', '古丽扎娜', '佟丽丫丫']; console.log(arr2[0]); console.log(arr2[1]); console.log(arr2[2]); console.log(arr2[3]); // 因为没有这个数组元素 所以输出的结果是 undefined </script> </head> <body> </body> </html>

    1.2 遍历

    <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>

    长度

    <script> // 数组长度 数组名.length var arr = ['关羽', '张飞', '马超', '赵云', '黄忠', '刘备', '姜维', 'pink']; for (var i = 0; i < 7; i++) { console.log(arr[i]); } console.log(arr.length); for (var i = 0; i < arr.length; i++) { console.log(arr[i]); } // 1. 数组的长度是元素个数 不要跟索引号混淆 // 2. arr.length 动态监测数组元素的个数 </script>

    案例

    <script> // 1. 求数组 [2,6,1,7, 4] 里面所有元素的和以及平均值。 // (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, average); // 想要输出多个变量,用逗号分隔即可 </script> <script> // 求数组[2,6,1,77,52,25,7]中的最大值 // 声明一个保存最大元素的变量 max。 // 默认最大值可以取数组中的第一个元素。 // 遍历这个数组,把里面每个数组元素和 max 相比较。 // 如果这个数组元素大于max 就把这个数组元素存到 max 里面,否则继续下一轮比较。 // 最后输出这个 max var arr = [2, 6, 1, 77, 52, 25, 7, 99]; var max = arr[0]; for (var i = 1; i < arr.length; i++) { if (arr[i] > max) { max = arr[i]; } } console.log('该数组里面的最大值是:' + max); </script> <script> // 将数组 ['red', 'green', 'blue', 'pink'] 转换为字符串,并且用 | 或其他符号分割 // 1.需要一个新变量用于存放转换完的字符串 str。 // 2.遍历原来的数组,分别把里面数据取出来,加到字符串里面。 // 3.同时在后面多加一个分隔符 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>

    2. 新增元素

    <script> // 1. 新增数组元素 修改length长度 var arr = ['red', 'green', 'blue']; console.log(arr.length); arr.length = 5; // 把我们数组的长度修改为了 5 里面应该有5个元素 console.log(arr); console.log(arr[3]); // undefined console.log(arr[4]); // undefined // 2. 新增数组元素 修改索引号 追加数组元素 var arr1 = ['red', 'green', 'blue']; arr1[3] = 'pink'; console.log(arr1); arr1[4] = 'hotpink'; console.log(arr1); arr1[0] = 'yellow'; // 这里是替换原来的数组元素 console.log(arr1); arr1 = '有点意思'; console.log(arr1); // 不要直接给 数组名赋值 否则里面的数组元素都没有了 </script>

    2.1 案例

    <script> // 新建一个数组,里面存放10个整数( 1~10) // 核心原理:使用循环来追加数组。 // 1、声明一个空数组 arr。 // 2、循环中的计数器 i 可以作为数组元素存入。 // 3、由于数组的索引号是从0开始的, 因此计数器从 0 开始更合适,存入的数组元素要+1。 var arr = []; for (var i = 0; i < 100; i++) { // arr = i; 不要直接给数组名赋值 否则以前的元素都没了 arr[i] = i + 1; } console.log(arr); </script>

    2.2 筛选

    <script> // 将数组 [2, 0, 6, 1, 77, 0, 52, 0, 25, 7] 中大于等于 10 的元素选出来,放入新数组。 // 1、声明一个新的数组用于存放新数据newArr。 // 2、遍历原来的旧数组, 找出大于等于 10 的元素。 // 3、依次追加给新数组 newArr。 // 方法1 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); // 方法2 var arr = [2, 0, 6, 1, 77, 0, 52, 0, 25, 7]; var newArr = []; // 刚开始 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>

    3. 数组案例

    翻转数组

    <script> // 将数组 ['red', 'green', 'blue', 'pink', 'purple'] 的内容反过来存放 // 1、声明一个新数组 newArr // 2、把旧数组索引号第4个取过来(arr.length - 1),给新数组索引号第0个元素 (newArr.length) // 3、我们采取 递减的方式 i-- var arr = ['red', 'green', 'blue', 'pink', 'purple', 'hotpink']; var newArr = []; for (var i = arr.length - 1; i >= 0; i--) { newArr[newArr.length] = arr[i] } console.log(newArr); </script>

    冒泡排序

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

    4.函数

    4.1 概念

    <script> // 1. 求 1~100的累加和 var sum = 0; for (var i = 1; i <= 100; i++) { sum += i; } console.log(sum); // 2. 求 10~50的累加和 var sum = 0; for (var i = 10; i <= 50; i++) { sum += i; } console.log(sum); // 3. 函数就是封装了一段可以被重复执行调用的代码块 目的: 就是让大量代码重复使用 function getSum(num1, num2) { var sum = 0; for (var i = num1; i <= num2; i++) { sum += i; } console.log(sum); } getSum(1, 100); getSum(10, 50); getSum(1, 1000); </script>

    4.2 使用

    <script> // 函数使用分为两步: 声明函数 和 调用函数 // 1. 声明函数 // function 函数名() { // // 函数体 // } function sayHi() { console.log('hi~~'); } // (1) function 声明函数的关键字 全部小写 // (2) 函数是做某件事情,函数名一般是动词 sayHi // (3) 函数不调用自己不执行 // 2. 调用函数 // 函数名(); sayHi(); // 调用函数的时候千万不要忘记加小括号 </script>

    4.3 带参数的函数

    行参和实参

    <script> // 1. 函数可以重复相同的代码 // function cook() { // console.log('酸辣土豆丝'); // } // cook(); // cook(); // 2. 我们可以利用函数的参数实现函数重复不同的代码 // function 函数名(形参1,形参2...) { // 在声明函数的小括号里面是 形参 (形式上的参数) // } // 函数名(实参1,实参2...); // 在函数调用的小括号里面是实参(实际的参数) // 3. 形参和实参的执行过程 function cook(aru) { // 形参是接受实参的 aru = '酸辣土豆丝' 形参类似于一个变量 console.log(aru); } cook('酸辣土豆丝'); cook('大肘子'); // 4. 函数的参数可以有,也可以没有个数不限 </script>

    例子

    <script> // 1. 利用函数求任意两个数的和 function getSum(num1, num2) { console.log(num1 + num2); } getSum(1, 3); getSum(3, 8); // 2. 利用函数求任意两个数之间的和 function getSums(start, end) { var sum = 0; for (var i = start; i <= end; i++) { sum += i; } console.log(sum); } getSums(1, 100); getSums(1, 10); // 3. 注意点 // (1) 多个参数之间用逗号隔开 // (2) 形参可以看做是不用声明的变量 </script>

    形参实参个数匹配

    <script> // 函数形参实参个数匹配 function getSum(num1, num2) { console.log(num1 + num2); } // 1. 如果实参的个数和形参的个数一致 则正常输出结果 getSum(1, 2); // 2. 如果实参的个数多于形参的个数 会取到形参的个数 getSum(1, 2, 3); // 3. 如果实参的个数小于形参的个数 多于的形参定义为undefined 最终的结果就是 NaN // 形参可以看做是不用声明的变量 num2 是一个变量但是没有接受值 结果就是undefined getSum(1); // NaN // 建议 我们尽量让实参的个数和形参相匹配 </script>

    4.4 返回值

    <script> // 1.函数是做某件事或者实现某种功能 // function cook(aru) { // console.log(aru); // } // cook('大肘子'); // 2. 函数的返回值格式 // function 函数名() { // return 需要返回的结果; // } // 函数名(); // (1) 我们函数只是实现某种功能,最终的结果需要返回给函数的调用者函数名() 通过return 实现的 // (2) 只要函数遇到return 就把后面的结果 返回给函数的调用者 函数名() = return后面的结果 // 3. 代码验证 function getResult() { return 666; } getResult(); // getResult() = 666 console.log(getResult()); // function cook(aru) { // return aru; // } // console.log(cook('大肘子')); // 4. 求任意两个数的和 function getSum(num1, num2) { return num1 + num2; } console.log(getSum(1, 2)); </script>

    案例

    <script> // 利用函数 求两个数的最大值 function getMax(num1, num2) { // if (num1 > num2) { // return num1; // } else { // return num2; // } return num1 > num2 ? num1 : num2; } console.log(getMax(1, 3)); console.log(getMax(11, 3)); </script> <script> // 利用函数求数组 [5,2,99,101,67,77] 中的最大数值。 function getArrMax(arr) { // arr 接受一个数组 arr = [5,2,99,101,67,77] 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]); var re = getArrMax([3, 77, 44, 99, 143]); console.log(re); </script>

    注意事项

    <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(1, 2); // 返回的是一个数组 console.log(re); // 4. 我们的函数如果有return 则返回的是 return 后面的值,如果函数么有 return 则返回undefined function fun1() { return 666; } console.log(fun1()); // 返回 666 function fun2() { } console.log(fun2()); // 函数返回的结果是 undefined </script>

    4.5 arguments

    <script> // arguments 的使用 只有函数才有 arguments对象 而且是每个函数都内置好了这个arguments function fn() { // console.log(arguments); // 里面存储了所有传递过来的实参 arguments = [1,2,3] // console.log(arguments.length); // console.log(arguments[2]); // 我们可以按照数组的方式遍历arguments for (var i = 0; i < arguments.length; i++) { console.log(arguments[i]); } } fn(1, 2, 3); fn(1, 2, 3, 4, 5); // 伪数组 并不是真正意义上的数组 // 1. 具有数组的 length 属性 // 2. 按照索引的方式进行存储的 // 3. 它没有真正数组的一些方法 pop() push() 等等 </script>

    例子

    <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(1, 2, 3, 4, 5)); console.log(getMax(11, 2, 34, 444, 5, 100)); </script>

    4.6 函数之间互相调用

    <script> // 函数是可以相互调用的 // function fn1() { // console.log(11); // fn2(); // 在fn1 函数里面调用了 fn2 函数 // } // fn1(); // function fn2() { // console.log(22); // } function fn1() { console.log(111); fn2(); console.log('fn1'); } function fn2() { console.log(222); console.log('fn2'); } fn1(); </script>

    输出2月份天数案例

    <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>

    4.7 函数两种调用方式

    // 函数的2中声明方式 // 1. 利用函数关键字自定义函数(命名函数) function fn() { } fn(); // 2. 函数表达式(匿名函数) // var 变量名 = function() {}; var fun = function(aru) { console.log('我是函数表达式'); console.log(aru); } fun('pink老师'); // (1) fun是变量名 不是函数名 // (2) 函数表达式声明方式跟声明变量差不多,只不过变量里面存的是值 而 函数表达式里面存的是函数 // (3) 函数表达式也可以进行传递参数 </script>

    5. 作用域

    5.1 概述

    <script> // 1.JavaScript作用域 : 就是代码名字(变量)在某个范围内起作用和效果 目的是为了提高程序的可靠性更重要的是减少命名冲突 // 2. js的作用域(es6)之前 : 全局作用域 局部作用域 // 3. 全局作用域: 整个script标签 或者是一个单独的js文件 var num = 10; var num = 30; console.log(num); // 4. 局部作用域(函数作用域) 在函数内部就是局部作用域 这个代码的名字只在函数内部起效果和作用 function fn() { // 局部作用域 var num = 20; console.log(num); } fn(); </script>

    5.2 变量作用域

    变量的作用域: 根据作用域的不同我们变量分为全局变量和局部变量。 从执行效率来看全局变量和局部变量: (1) 全局变量只有浏览器关闭的时候才会销毁,比较占内存资源 (2) 局部变量 当我们程序执行完毕就会销毁, 比较节约内存资源

    <script> // 1. 全局变量: 在全局作用域下的变量 在全局下都可以使用 // 注意 如果在函数内部 没有声明直接赋值的变量也属于全局变量 var num = 10; // num就是一个全局变量 console.log(num); function fn() { console.log(num); } fn(); // console.log(aru); // 2. 局部变量 在局部作用域下的变量 后者在函数内部的变量就是 局部变量 // 注意: 函数的形参也可以看做是局部变量 function fun(aru) { var num1 = 10; // num1就是局部变量 只能在函数内部使用 num2 = 20; } fun(); // console.log(num1); // console.log(num2); </script>

    5.3 没有块级作用域

    <script> // js中没有块级作用域 js的作用域: 全局作用域 局部作用域 现阶段我们js 没有 块级作用域 // 我们js 也是在 es6 的时候新增的块级作用域 // 块级作用域 {} if {} for {} // java // if(xx) { // int num = 10; // } // 外面的是不能调用num的 if (3 < 5) { var num = 10; } console.log(num); </script>

    5.4 作用域链

    作用域链 : 内部函数访问外部函数的变量,采取的是链式查找的方式来决定取那个值 这种结构我们称为作用域链 就近原则

    <script> var num = 10; function fn() { // 外部函数 var num = 20; function fun() { // 内部函数 console.log(num); } fun(); } fn(); </script>

    案例

    <script> // 案例1 : 结果是几? function f1() { var num = 123; function f2() { var num = 0; console.log(num); // 站在目标出发,一层一层的往外查找 } f2(); } var num = 456; f1(); // 案例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); //a的值 ? console.log(b); //b的值 ? } } } fn1(); </script>

    6. 预解析

    6.1 预解析

    我们js引擎运行js 分为两步: 预解析 代码执行 (1). 预解析 js引擎会把js 里面所有的 var 还有 function 提升到当前作用域的最前面 (2). 代码执行 按照代码书写的顺序从上往下执行 预解析分为 变量预解析(变量提升) 和 函数预解析(函数提升) (1) 变量提升 就是把所有的变量声明提升到当前的作用域最前面 不提升赋值操作 (2) 函数提升 就是把所有的函数声明提升到当前作用域的最前面 不调用函数

    <script> // 1问 console.log(num); // 2问 console.log(num); // undefined 坑 1 var num = 10; // 相当于执行了以下代码 // var num; // console.log(num); // num = 10; // 3问 function fn() { console.log(11); } fn(); // 4问 fun(); // 报错 坑2 var fun = function() { console.log(22); } // 函数表达式 调用必须写在函数表达式的下面 // 相当于执行了以下代码 // var fun; // fun(); // fun = function() { // console.log(22); // } </script>

    6.2 案例

    // // 相当于执行了以下操作 // // var num; // // function fun() { // // var num; // // console.log(num); // // num = 20; // // } // // num = 10; // // fun();

    // // 相当于以下代码 // // var num; // // function fn() { // // var num; // // console.log(num); // // num = 20; // // console.log(num); // // } // // num = 10; // // fn();

    // 相当于以下代码 // var a; // function f1() { // var b; // var a; // b = 9; // console.log(a); // console.log(b); // a = '123'; // } // a = 18; // f1();

    // 以下代码 // function f1() { // var a; // a = b = c = 9; // // 相当于 var a = 9; b = 9; c = 9; b 和 c 直接赋值 没有var 声明 当 全局变量看 // // 集体声明 var a = 9, b = 9, c = 9; // console.log(a); // console.log(b); // console.log(c); // } // f1(); // console.log(c); // console.log(b); // console.log(a);

    参考: 代码一 代码二

    Processed: 0.010, SQL: 9