批改状态:合格
老师批语:很不错, 上课认真听了
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>let的用法</title></head><body><!-- ul>li{item$}*5 --><ul><li>item1</li><li>item2</li><li>item3</li><li>item4</li><li>item5</li></ul><script>// 1. let不支持重复声明,但是支持重复赋值let str1 = "aaa";// let str1 = "bbb";// 上面这个行代码显示 “Identifier 'str1' has already been declared” 这样的报错,表示变量str1已经被使用,即不能重复声明str1 = "bbb";console.log(str1); // 输出:bbbstr1 = "ccc";console.log(str1); // 输出:ccc// 上面四行代码可以看出,是支持重复赋值的/*====================================================================================================================*/// 2. let不存在变量提升,无论是在全局作用域还是函数作用域// console.log(str2);// console.log(str2); 这行代码显示这样的报错:Cannot access 'str2' before initialization(不能在初始化以前使用str2)// 说明在全局作用域下不存在变量声明的提升let str2 = "hello";console.log(str2); // 输出:hellofunction demo() {// console.log(str3); Cannot access 'str2' before initializationlet str3 = "world";console.log(str3);}demo(); // 输出: world// 从上面几行代码,也可以看出在函数作用域下也不支持变量声明提升/*=====================================================================================================================*/// 3. let支持块级作用域if (true) {let str4 = "didi";console.log(str4); // 输出:didi}// console.log(str4); 输出:str4 is not defined// 说明在if(){}这个代码块中,str4是有效的,但是在这个块级作用域以外就无效了// let块级作用域示例let lis = document.querySelectorAll("li");for (var i = 0; i < lis.length; i++) {lis[i].addEventListener("click", function () {console.log("点击了 item" + (i + 1));});}// 如果for()代码块中是用var声明的变量,最后不管你点击哪个item,都会出现item6,这就是var 不支持块作用域的原因,而且var声明会被提升// 此案例中var声明会提升到全局,导致addEventListener这个代码块中的 i 不能共享到全局变量,当循环执行完以后,这个 i 就已经变成了 6// 而let 就不一样,它支持块级作用域,所以每次循环的时候都会形成一个块级作用域,那么addEventListener这个代码块中的 i 就能得到其真实对应的值for (let i = 0; i < lis.length; i++) {lis[i].addEventListener("click", function () {console.log("点击了 item" + (i + 1));});}</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>const的用法</title></head><body><script>// const声明的是一种特殊变量(只读变量),就是所谓的常量// 1. const声明的常量必须初始化// const NAME;// 报错信息:Missing initializer in const declaration (在const声明中缺少初始化)const NAME = "jack";console.log(NAME); // jack/********************************************************************************************/// 2. const 也不支持重复声明,并且不能重新赋值// const NAME = "mike";// 报错信息:Identifier 'NAME' has already been declared(变量NAME已经被使用了)// NAME = "mike";// console.log(NAME);// 报错信息:Assignment to constant variable (常量类型的变量赋值出错)/********************************************************************************************/// 3. const 支持块级作用域if (true) {const GENDER = "male";console.log(GENDER); // male}// console.log(GENDER); 报错: GENDER is not defined</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>let与const的区别</title></head><body><script>// let与const的区别:// 1. 相同之处:都不能重复声明,都支持块级作用域// 2. 不同之处:let允许重新赋值(更新),而const禁止更新// 实际开发中可能存在两种风格:// 1. 全部都用const,除非这个数据后期会有改变// 2. 可能会更新的或常用的都使用let,除非不会或不太可能被修改的才用const// 基础上面两点总结:在开发中都尽量使用const会更加严谨,如果出现某个变量报错信息,修改它为let即可// 有一些数据类型强烈推荐使用const,比如:对象或数组// 1. 数组const pics = ["image1", "image2", "image3"];console.log(pics); // (3) ["image1", "image2", "image3"]// 对数组中的元素进行增删改查也是没有问题的pics.push("image4");console.log(pics); // (4) ["image1", "image2", "image3", "image4"]pics.splice(3, 2, "image5", "image6");console.log(pics); // (5) ["image1", "image2", "image3", "image5", "image6"]// 2. 对象const obj = {name: "jack",age: 21,email: "jack@qq.com",};console.log(obj.age); // 21console.log(obj.name); // jackobj.sex = "male";console.log(obj.sex); // male// 3. DOM操作时const h1 = document.createElement("h1");const body = document.querySelector("body");h1.innerText = "标题";h1.style.color = "red";body.append(h1);</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Document</title></head><body><script>// 1. 数组示例:取出里面的元素分别赋值给变量const arr = ["num1", "num2", "num3"];// 传统做法let num1 = arr[0];let num2 = arr[1];let num3 = arr[2];console.log(num1, num2, num3); // num1 num2 num3// 使用解构语法let [n1, n2, n3] = arr;console.log(n1, n2, n3); // num1 num2 num3// 2. 对象示例:取出对象中的每个属性const obj = {name: "jack",age: 20,email: "jack@qq.com",};// 传统做法let personName = obj.name;let personAge = obj.age;let personEmail = obj.email;console.log(personName, personAge, personEmail); // jack 20 jack@qq.com// 使用解构语法let { name, age, email } = obj;console.log(name, age, email); // jack 20 jack@qq.com// 3. 在书写代码时,可能会直接使用解构语法为数组或对象赋值let [p1, p2, p3] = ["pic1", "pic2", "pic3"];console.log(p1, p2, p3); // pic1 pic2 pic3// 注意点一:解构变量的声明必须初始化// let [a, b, c];// 报错信息:Missing initializer in destructuring declaration(解构声明中缺少初始值设定项)let [a1, a2, a3] = [10, 20, 30];console.log(a1 + a2 + a3); // 60// 如果有值未初始化let [b1, b2, b3] = [10, 20];console.log(b1 + b2 + b3); // NAN// 声明的同时赋上默认值let [c1, c2, c3 = 50] = [10, 20];console.log(c1 + c2 + c3); // 80// 通过上面示例:可以理解成,此种书写方式下,左边看成是变量的声明,右边就是根据声明的变量为它赋值// 注意点二:模板语法// 解构数组使用 [] , 解构对象使用 {} ,一定要一一对应// 在解构的过程中,是有两部分在参与,整个过程可以理解为一个解构表达式// 1. 解构的源就是解构表达式的右边部分// 2. 解构的目标就是解构表达式的左边部分</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>数组模型的解构</title></head><body><script>const arr1 = ["name1", "name2", "name3"];// 1. 解构所有元素let [name1, name2, name3] = arr1;console.log(name1, name2, name3); // name1 name2 name3// 2. 解构部分元素,使用空占位符let [n1, , n3] = arr1;console.log(n1, n3); // name1 name3// 3. 使用解构表达式更新变量let num1 = 10;let num2 = 20;console.log(num1 + num2); // 30[num1, num2] = [30, 40];console.log(num1 + num2); // 70// 4. 解构默认值const arr2 = ["blue", "green", "yellow"];let [c1, c2 = "black", c3] = arr2;console.log(c1, c2, c3); // blue green yellowlet [d1, d2, d3, d4] = arr2;console.log(d1, d2, d3, d4); // blue green yellow undefinedlet [e1, e2, e3, e4 = "black"] = arr2;console.log(e1, e2, e3, e4); // blue green yellow black// 变量声明时使用默认值的话,如果数组中有对应的元素,那么会覆盖默认值,如果没有,那么会使用默认值// 5. 嵌套解构const arr3 = [1, 2, [3, 4], [[5, 6]], 7, 8];// 取出所有数字let [a1, a2, [a3, a4], [[a5, a6]], a7, a8] = arr3;console.log(a1, a2, a3, a4, a5, a6, a7, a8); // 1 2 3 4 5 6 7 8// 取出 5 和 6let [, , [,], [[b5, b6]], ,] = arr3;console.log(b5, b6); // 5 6// 6. 函数参数中使用数组解构function demo([x, y = 30]) {return x + y;}console.log(demo([10, 20])); // 30console.log(demo([10])); // 40// 7. 剩余运算符解构const arr4 = [10, 20, 30, 40, 50];let [r1, ...r4] = arr4;console.log(r1, r4); // 10 (4) [20, 30, 40, 50]// 相当于把后面的参数解析成一个数组r4,let声明中的...r4,表示将数组r4展开,以便获取后面的所有元素,而r4就是保存这些元素的数组// 8. 解构字符串let str = " hello world ";let [s1, s2, s3] = str;console.log(s1, s2, s3); // h e 因为hello前面有一个空格,所以只得到 h elet [, , , , , , ...ss] = str.trim(); // 将字符串两边空白去掉console.log(ss); // (5) ["w", "o", "r", "l", "d"] 获得一个数组</script></body></html>
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>对象模型的解构</title></head><body><script>// 1. 基本解构const obj1 = { num1: 10, num2: 30 };let { num1, num2 } = obj1;console.log(num1, num2); // 10 30let { n1, n2 } = obj1;console.log(n1, n2); // undefined undefined// 解构对象时,变量的声明与对象中的属性名要一致,否则解析不了// 2. 嵌套解构const obj2 = {name: "alice",age: 20,score: {php: 80,js: {basis: 90,advance: 78,},},hobby: {h1: "book",h2: "run",},};// 解析对象中的hobbylet { hobby } = obj2;console.log(hobby); // {h1: "book", h2: "run"}// 解析scroe-->js-->basislet {score: {js: { basis },},} = obj2;console.log(basis); // 90// 按照模板将对应的属性名放入声明中就能很好的解析了,仔细一点就不会出错// 3. 多次解构// 解构出advance和h2let {score: {js: { advance },},hobby: { h2 },} = obj2;console.log(advance, h2); // 78 "run"// 4. 解构声明中可使用变量别名(解决不同对象中出现命名冲突的问题)const obj3 = {name: "jack",age: 30,};let { name, age } = obj2; // alice 20// let { name, age } = obj3; //Identifier 'name' has already been declared,如果变量名之前被使用过,现在就不能再使用了,所以要取别名console.log(name, age);let { name: objName, age: objAge } = obj3;console.log(objName, objAge); // jack 30// 5. 解构声明中可设置默认值const obj4 = { a: "hello", b: "world", c: "yes" };let { a, b, c = "嘿嘿" } = obj4;console.log(a, b, c); // hello world yes 如果对象中存在对应的值,会覆盖默认值let { a: obja, b: objb, c: objc, d = "no" } = obj4;console.log(d); // no 如果对象中不存在对应的值,那么会使用声明中的默认值// 6. 解构表达式更新变量let s1 = 10;let s2 = 20;console.log(s1 + s2); // 30({ s1, s2 } = { s1: 50, s2: 60 });// 对象解构与数组解构的不同:1. 表达式右边要添加变量名 2. 表达式外层要套上一对小括号()console.log(s1 + s2); // 110// 7. 函数参数中使用对象解构function show({ number1: x, number2: y }) {console.log(x * y); // 50y = 6;console.log(x + y); // 11}show({ number1: 5, number2: 10 });// 如果参数中有默认值,会优先使用参数的值// 8. 解构剩余参数const obj5 = {personName: "tom",personAge: 18,personEmail: "tom@qq.com",personHobby: "book",};let { personName, personAge, ...person } = obj5;console.log(person); // {personEmail: "tom@qq.com", personHobby: "book"}// 剩余参数会组成一个新的对象</script></body></html>
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号