JSCORE04
目录
前言
一、复习
二、forEach
三、reduce
四、展开语法
五、解构语法
六、形参默认值
七、剩余参数
总结
前言
JSCORE04学习开始
一、复习
- JS的第6个版本, 带来了大量的新特性, 新语法
- let/const : 两个新的声明变量的方式
- 新的作用域
- 脚本: 对应
全局
, 用于存放自定义
的 全局属性- 块级: 对应
局部作用域
, 比匿名函数自调用语法更简单的 创建局部作用域
- 更加安全
- const: 声明时必须赋值, 后续无法修改
- 声明提升
- 依然存在提升, 但是 提升后处于
暂存死区
状态, 不允许使用; 直到代码执行到 声明所在行才能解锁- 模板字符串
- 支持换行, 可以书写更加易读的 HTML 代码
- 支持在字符串中书写JS代码. 让字符串拼接操作更方便
- 箭头函数
- 格式更简单:
()=>{}
- 语法糖
- 形参只有一个, () 可以省略
- 函数体只有一行,
{return }
省略- this: 没有this; 按照
作用域链
原则, 向上级作用域找- 数组高阶函数
- 实际开发时, 数据通常从服务器的数据库获取 -- 查询出来的都是数组类型
- every : 每一个元素都符合条件 -- 类似 逻辑与 &&
- some : 至少一个元素符合条件 -- 类似 逻辑或 ||
- filter : 满足条件的元素过滤出来
- map : 映射; 把数组中的元素 按照一定的规范, 修改成其他的样子, 得到新的数组
二、forEach
<!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>forEach 10:11</title> </head> <body> <script> // 遍历数组的方式 有 4 种 const names = ['lucy', 'lily', 'john', 'tom'] // 1. for - 利用length 属性 for (let i = 0; i < names.length; i++) { console.log(i, names[i]); } // 2. for..in : 此方案是遍历对象类型的通用方案, 非数组专属 for (const key in names) { // key: 属性名 -- 字符串 console.log(key, names[key]) } // 如果打印多个元素, 类型不同, 则后台会有特殊显示 console.log(1, 'mike', 'xxx'); // 3. for..of : ES6新增的 数组专属的遍历方案 for (const value of names) { console.log(value) } // 4. forEach: 原型中提供此方法, 就可以用来遍历 // -- 得益于 箭头函数的 语法糖, 格式更简单 // -- 单纯遍历数组元素, 没有返回值 names.forEach((value, index, array) => { console.log(index, value) }) </script> </body> </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>练习 10:26</title> </head> <body> <script> var nums = [12, 436, 787, 345, 4, 67, 54, 32, 54, 65] // 要求: 计算出 数组中元素的总和 var total = 0 for (const n of nums) { total += n } console.log(total) /// var total = 0 nums.forEach(v => total += v) console.log(total) / class Goods { constructor(gname, price, count) { this.gname = gname this.price = price this.count = count } } const list = [ new Goods("苹果", 10, 20), new Goods("香蕉", 6, 15), new Goods("鸭梨", 12, 10), new Goods("葡萄", 20, 30), ] console.log(list) var total = 0 for (const g of list) { total += g.price * g.count } console.log(total); var total = 0 list.forEach(v => total += v.price * v.count) console.log(total) </script> </body> </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>练习 10:48</title> </head> <body> <script> class Goods { constructor(gname, price, count, sale) { // 商品名 单价 数量 是否售出 this.gname = gname this.price = price this.count = count this.sale = sale } } var list = [ new Goods('黄焖鸡', 23, 10, true), new Goods('螺蛳粉', 17, 1, false), new Goods('红烧肉盖饭', 31, 20, true), new Goods('麻辣烫', 25, 12, false), ] //普通 var total = 0 list.forEach(value => { if (value.sale) { total += value.price * value.count } }) console.log(total) // 精巧 var total = 0 // 数学设定: 任何数字 x 0 = 0 // 隐式类型转换: 在数学运算表达式中, true -> 1 false -> 0 // sale 为假时, total += 0 list.forEach(v => total += v.price * v.count * v.sale) console.log(total) </script> </body> </html>
三、reduce
<!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>reduce 11:18</title> </head> <body> <script> // reduce: 合并; 把数组中的元素 合并成 一个值 var nums = [12, 43, 54, 65, 76, 87, 89] // 效果: 累加每个元素 // reduce(回调函数, 盒子初始值) // - 参数2: 默认值是 数组的第一个元素的值, 通常会手动设定为0 // - 参数1: 每个元素都会被执行一次, 把自身的值 和 传入的box中的值 操作后返回给下一个元素 var x = nums.reduce((box, value) => { return box + value }, 0) var x = nums.reduce((box, value) => box + value, 0) console.log(x) </script> </body> </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>展开语法</title> </head> <body> <script> // 计算出任意个数字的总和 function sum() { // 伪数组/类(似)数组 // 外观和数组一样, 用数字做属性名, 带有 length 属性 // 但是 原型 不是数组 Array.prototype // 则其无法使用数组的方法 console.log(arguments) var total = 0 // for..of : 只要带 length 属性, 就能遍历 for (const num of arguments) { total += num } return total } console.log(sum(12, 43, 54, 65, 7687, 87)); console.log(sum(12, 43, 54)); var nums = [12, 34, 546, 67, 878, 98] // ES6前: 用 apply 把数组打散,拆散 console.log(sum.apply(1, nums)) // ES6后: 提供新的运算符 ... 可以去掉数组的[]包围 console.log(sum(...nums)) // ... 可以去掉 {} 和 [] 的包围 var m = { x: 10, y: 20 } // 如果有同名属性, 后写的覆盖先写的 var n = { ...m, z: 30, x: 40 } console.log(n) var aa = [11, 22, 33] var bb = [44, 55, 66] // 以前: 用 concat 方法来合并数组 var cc = aa.concat(bb, 77, 88) console.log(cc) var cc = [...aa, ...bb, 77, 88] console.log(cc) </script> </body> </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>解构语法 14:01</title> </head> <body> <script> // 把数组 或 对象 中的值 解放出来, 存储在属性里 var names = ['mike', 'lucy', 'lily', 'john'] // 传统方案 // var a = names[0] // var b = names[1] // var c = names[2] // 可选解构 var [x, , y, z] = names console.log(x, y, z); // 新语法 var [a, b, c] = names console.log(a, b, c) // 巧妙的衍生用法: 互换变量值 var m = 10 var n = 20; // 必须用分号间隔, 否则会认为是 20[m,n] 产生歧义 [m, n] = [n, m] // 解析 // 1. 制作1个数组 [n, m] -> [20, 10] // 2. 解构数组 [m, n] = [20, 10] // 结果: m = 20; n = 10 console.log('m', m) console.log('n', n) </script> </body> </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>对象的解构 14:15</title> </head> <body> <script> var emp = { ename: "泡泡", age: 19, phone: '18823240404', boyFriend: '小鱼' } //传统 // var ename = emp.ename // var age = emp.age // var phone = emp.phone // ctrl + i : 有提示 // 别名语法 {属性名: 别名} var { age, ename, phone, boyFriend: bf } = emp console.log(ename, age, phone, bf); </script> </body> </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>练习</title> </head> <body> <script> var emp = { ename: "凯凯", alias: '追风少年', age: 34, skills: ['吃饭', '睡觉', '写BUG'] } var { age, alias, ename, skills: [s1, s2, s3] } = emp console.log(age, alias, ename, s1, s2, s3); </script> </body> </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>形参解构 14:41</title> </head> <body> <script> var c1 = { width: 10, length: 20, height: 30 } // 体积 function volume(cube) { const { width: w, height: h, length: l } = cube return w * h * l // return cube.width * cube.length * cube.height } // 面积 // 形参解构语法: 直接把传入的实参 进行解构 function area({ width: w, height: h, length: l }) { // const { width: w, height: h, length: l } = cube return 2 * (l * w + l * h + w * h) // return 2 * (cube.width * cube.length + cube.length * cube.height + cube.width * cube.height) } volume(c1) </script> </body> </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>形参默认值 15:11</title> </head> <body> <script> // 形参指定默认值 function show(uname = '凯凯') { console.log(uname); } show() // 不传递实参, 则采用默认值 凯凯 show("泡泡") // 传递实参, 则采用传递的值 </script> </body> </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>剩余参数 15:15</title> </head> <body> <script> // 剩余参数 用于代替 arguments 属性 // arguments的问题 // 1. 隐式的: 导致很多人不知道其存在 // 2. 伪数组: 缺少数组的方法, 使用时不方便 // ... 这个运算符 有两种用途 // ...数组, ...对象: 展开操作 // ...形参 : 剩余参数; 代表这个形参接收所有的(没人要的)实参 function sum(x, y, ...args) { console.log(args); } sum('泡泡', '凯凯', '铭铭', '亮亮') </script> </body> </html>
总结
- forEach: 单纯的遍历数组
- 如果是伪数组, 需要检查其
原型中
是否有forEach 可以用- 通用:
for..of
只要有 length 属性, 就能遍历- reduce(
鸡肋
): 合并数组元素
- 但是 因为逻辑较为复杂, 使用较少