批改状态:合格
老师批语:
// 1. 赋值// 1.1 值传递:原始类型(string,number,bool)let a = 1;let b = a;console.log("a=%d,b=%d", a, b);a = 2;console.log("a=%d,b=%d", a, b);// 1.2 引用传递:引用类型(object,array)let obj1 = { a: 1, b: 2 };console.log(obj1);let obj2 = obj1;obj1.a = 2;console.log(obj2);// 引用类型指向的是相同内存地址// 2. 传参// 传参时,不论什么类型,都是“值传递”const f1 = (x) => (x = 10);let m = 5;f1(m);// 入参:调用函数时传入的参数,简称:入参// 函数中对参数的更新,并不会影响到入参console.log("m = %d", m);const f2 = (x) => (x.a = 10);let o = { a: 1, b: 2 };f2(o);console.log(o);// 看上去函数中对于o.a的更新生效,实际上只是值传递// 对于引用类型,只有全新赋值才算是更新,修改属性不算。const obj = { x: 1, y: 2 };obj.x = 20;// 函数中对于对象参数/引用参数的更新并没有影响// 深拷贝:值传递// 浅拷贝:引用传递
// 1. 模板字面量:将表达式嵌入字符串中let a = 1,b = 2;let res = a + " + " + b + " = " + (a + b);console.log(res);// 模板字面量使用反应“`”res = `${a} + ${b} = ${a + b}`;console.log(res);// 模板字面量的组成:// 1. 字符串字面量:“+,=”// 2. 变量或表达式:a,b,(a + b)let menu = ["首页", "视频", "文章"];let htmlStr = `<ul><li><a href="">${menu[0]}</a></li><li><a href="">${menu[1]}</a></li><li><a href="">${menu[2]}</a></li></ul>`;console.log(htmlStr);document.body.insertAdjacentHTML("beforeend", htmlStr);// document.body.insertAdjacentHTML("beforebegin",htmlStr);// 2. 标签函数:自定义模板字面量的行为// 遍历,加样式,动态渲染,放到迭代器中循环// let hello = name => alert(name);// hello("朋友");// hello`朋友`;// 模板字面量可以当参数使用,函数调用的小括号都可以不写// 使用自定义函数处理模板字面量,他的参数约定// 1. 第一个参数:模板字面量中的字符串字面量组成的数组// 2. 从第二个参数开始,将模板字面量中的变量依次传入let sum = (strs, a, b) => {console.log(strs);console.log(a, b);};sum(["+", "=", ""], a, b);sum`${a} + ${b} =`;sum = (strs, ...args) => {console.log(strs);console.log(args);};sum`${a}+${b} = `;
//解构赋值:快速从集合中(数组/对象)解构出独立变量//1. 数组let [a, b, c] = [1, 2, 3];console.log(a, b, c);[a, b] = [1, 2, 3];console.log(a, b);[a, b, c, d] = [1, 2, 3];console.log(a, b, c, d);// 还可以使用默认值[a, b, c, d = "xxx"] = [1, 2, 3];console.log(a, b, c, d);// 取部分值,其他值通过rest语法压入数组[a, b, ...c] = [1, 2, 3, 4, 5];console.log(a, b, c);// 想拿到固定位置的值[, , a, ,] = [1, 2, 3, 4, 5];console.log(a);// 两个值交换let x = 1,y = 2;// let t// t = x;// x = y;// y = t;// console.log(x,y);[y, x] = [x, y];console.log(x, y);// 2. 对象解构let { id, name } = { id: 10, name: "phone" };console.log(id, name);// 属性名与变量名必须对应,顺序无所谓//当变量名冲突时,可以使用别名let email = "admin@php.cn";let { role, email: userEmail } = { role: "user", email: "user@php.cn" };console.log(userEmail);console.log(email);// 3. 参数解构// 数组传参let sum = ([a, b]) => a + b;console.log(sum([10, 20]));//对象传参let getUser = ({ name, email }) => [name, email];console.log(getUser({ email: "tp@php.cn", name: "TP" }));
总结:太好用了。
注意:结构数量不完全匹配的时候,如何接解构的值
[, , a, ,] = [1, 2, 3, 4, 5];
let user = {userName: 'tp',userEmail: 'tp@php.cn',getInfo:function() {return `${this.userName} ( ${this.userEmail} )`;}}console.log(user.getInfo());let {userName,userEmail}=user;console.log(userName,userEmail);user = {// 当属性名与同一个作用域中的变量名向同时// 可以直接使用属性名来引用该变量的值// userName:userName,// userEmail:userEmail,userName,userEmail,// getInfo:function() {// return `${this.userName} ( ${this.userEmail} )`;// }// 方法也可以简化getInfo() {return `${this.userName} ( ${this.userEmail} )`;}// getInfo:()=>// return `${this.userName} ( ${this.userEmail} )`;}console.log("简化后",user.getInfo());//箭头函数中的this总是指向定义它的作用域(静态作用域/词法作用域),并非调用是的作用域// js中,只有函数和块才能创建作用域// user对象不能创建作用域 此时的this指向了上user的作用域/作用域链;// 全局没有userName,userEmail,所以输出 undefined。
<button>click</button><script>// function f1() {}// console.dir(f1);// bind,call,apply定义在原型上的方法function hello(name) {this.name = name;console.log(this.name);}const obj = {name: "admin",// hello(name) {// this.name = name;// console.log(this.name);// },// 代码冗余};//经典调用console.log(hello("hi 你好"));//bind()不会立即执行,只返回一个函数声明// 将hello()这个函数绑定到obj对象上,第二个参数是hello的参数let f = hello.bind(obj, "tp");console.log(f());// call / apply 立即执行//将hello()这个函数绑定到obj对象上,第二个是hello的参数f = hello.call(obj, "xx");console.log(f);//使用apply第二个参数要是数组f = hello.apply(obj, ["yy"]);console.log(f);//bind()应用案例:动态改变thisdocument.querySelector("button").addEventListener("click",function () {console.log(this.name);console.log(this);document.body.appendChild(document.createElement("p")).innerHTML="欢迎"+this.name;}.bind({ name: "新对象" }));
总结:bind不会立即执行,call 和 apply 立即执行 其中apply 要求第二个参数是数组
使用此三个方法的好处是可以动态改变this指向,相应的也会是代码可读性变差。
const product = {data: [{ name: "电脑", price: 9000, num: 5 },{ name: "手机", price: 5000, num: 10 },{ name: "相机", price: 8000, num: 3 },],// getAmounts(){// return this.data.reduce((t,c)=>(t += c.price*c.num),0)// },//访问器属性//将方法伪造成一个属性get total(){return this.data.reduce((t,c)=>(t += c.price*c.num),0)},set setPrice(price){this.data[1].price = price;}};// console.log("总金额:", product.getAmounts());console.log("总金额:", product.total);product.setPrice = 7999;console.log("总金额:", product.data[1]);
总结:感觉很重要的样子。
// let user = {// name: "phone",// get name() {// return "HUAWEI";// },// set name(value) {// this.name = value;// },// };//访问器属性优先级高于同名的普通属性// console.log(user.name);// 怎么解决普通属性与访问器属性重名问题?let user = {data:{name},get name() {return this.data.name;},set name(value) {this.data.name = value;},};user.name = "HUAWEI";console.log(user.name);
总结:开发中尽量避免访问器属性与不同属性重名。
// let score = 64;//单分支// if (score >= 60) {// console.log("及格");// }// let score = 54;// // 双分支// if (score >= 60) {// console.log("及格");// //默认分支// } else {// console.log("补考");// }let score = 100;// 双分支if (score >= 60 && score < 80) {console.log("合格");//默认分支} else if (score >= 80 && score <= 100) {console.log("学霸");} else if (score > 100 || score < 0) {console.log("非法数据");} else {console.log("补考");}// switch 来简化多分支// 只要是区间一定要用true,switch是严格匹配score = 70;switch (true) {case score >= 60 && score < 80:console.log("合格");break;case score >= 80 && score <= 100:console.log("学霸");break;case score > 100 || score < 0:console.log("非法数据");break;default:console.log("补考");}// 一般区间判断不用switch,用if更直观// switch 一般用做单值判断let response = 'Success';switch (response.toLowerCase()) {case 'fail':console.log("请求失败");break;case 'success':console.log("请求成功");break;default:console.log("未知错误");}// 三元运算符// 条件 ? true: false;// if (score >= 60) {// console.log("及格");// //默认分支// } else {// console.log("补考");// }console.log(score >= 60 ? "及格" : "补考");
总结:作为重要内容。三元运算符简化了双分支条件语句。熟练运用可以简化代码,看起来更优雅。
值判断尽量使用switch,如果是区间判断一定要使用true作为条件。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号