思维导图
一、作用域
1.1 局部作用域
let和const声明的才有块作用域
1.2 全局作用域
1.3 作用域链
1.4 JS垃圾回收机制
1.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> </head> <body> <script> // 简单的写法 // function outer() { // let a = 10 // function fn() { // console.log(a) // } // fn() // } // outer() // 常见的闭包的形式 外部可以访问使用 函数内部的变量 // function outer() { // let a = 100 // function fn() { // console.log(a) // } // return fn // } // outer() === fn === function fn() {} // const fun = function fn() { } // // 常见的写法2 // function outer() { // let a = 100 // return function () { // console.log(a) // } // } // const fun = outer() // fun() // 调用函数 // 外面要使用这个 10 // 闭包的应用 // 普通形式 统计函数调用的次数 // let i = 0 // function fn() { // i++ // console.log(`函数被调用了${i}次`) // } // 因为 i 是全局变量,容易被修改 // 闭包形式 统计函数调用的次数 function count() { let i = 0 function fn() { i++ console.log(`函数被调用了${i}次`) } return fn } const fun = count() </script> </body> </html>
1.6 变量提升
变量提升,只提升声明,不提升赋值
<!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> </head> <body> <script> // 1. 把所有var声明的变量提升到 当前作用域的最前面 // 2. 只提升声明, 不提升赋值 // var num // console.log(num + '件') // num = 10 // console.log(num) function fn() { console.log(num) var num = 10 } fn() </script> </body> </html>
二、函数进阶
2.1 函数提升
只提升函数声明,不提升函数调用,但不提倡先调用后声明。
<!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> </head> <body> <script> var fun // 1. 会把所有函数声明提升到当前作用域的最前面 // 2. 只提升函数声明,不提升函数调用 // fn() // function fn() { // console.log('函数提升') // } // fun() // var fun = function () { // console.log('函数表达式') // } // 函数表达式 必须先声明和赋值, 后调用 否则 报错 </script> </body> </html>
函数表达式必须先声明赋值,后调用,否则报错,
2.2 函数参数
2.2.1 动态参数
是伪数组,有序号(下标,索引),但没有数组常用方法push、pop、shift、unshift
2.2.2 剩余参数
剩余参数是真数组
<!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> </head> <body> <script> function getSum(a, b, ...arr) { console.log(arr) // 使用的时候不需要写 ... } getSum(2, 3) getSum(1, 2, 3, 4, 5) </script> </body> </html>
2.2.3 展开运算符(区别于剩余参数)
数组没有求最大值的方法,而Math.max和Math.min不接收数组作为参数。
2.3 箭头函数(重要)
2.3.1 基本语法
<!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> </head> <body> <script> // const fn = function () { // console.log(123) // } // 1. 箭头函数 基本语法 // const fn = () => { // console.log(123) // } // fn() // const fn = (x) => { // console.log(x) // } // fn(1) // 2. 只有一个形参的时候,可以省略小括号 // const fn = x => { // console.log(x) // } // fn(1) // // 3. 只有一行代码的时候,我们可以省略大括号 // const fn = x => console.log(x) // fn(1) // 4. 只有一行代码的时候,可以省略return // const fn = x => x + x // console.log(fn(1)) // 5. 箭头函数可以直接返回一个对象 // const fn = (uname) => ({ uname: uname }) // console.log(fn('刘德华')) </script> </body> </html>
箭头函数属于表达式函数,不存在函数提升。
2.3.2 箭头函数的参数
<!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> </head> <body> <script> // 1. 利用箭头函数来求和 const getSum = (...arr) => { let sum = 0 for (let i = 0; i < arr.length; i++) { sum += arr[i] } return sum } const result = getSum(2, 3, 4) console.log(result) // 9 </script> </body> </html>
2.3.3 箭头函数this
三、解构赋值
3.1 数组解构
而且返回的是真数组
3.2 对象解构
如果已经存在同名变量,对象结构时可以重新命名
数组对象结构
<!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> </head> <body> <script> // 1. 这是后台传递过来的数据 const msg = { "code": 200, "msg": "获取新闻列表成功", "data": [ { "id": 1, "title": "5G商用自己,三大运用商收入下降", "count": 58 }, { "id": 2, "title": "国际媒体头条速览", "count": 56 }, { "id": 3, "title": "乌克兰和俄罗斯持续冲突", "count": 1669 }, ] } // 需求1: 请将以上msg对象 采用对象解构的方式 只选出 data 方面后面使用渲染页面 // const { data } = msg // console.log(data) // 需求2: 上面msg是后台传递过来的数据,我们需要把data选出当做参数传递给 函数 // const { data } = msg // msg 虽然很多属性,但是我们利用解构只要 data值 function render({ data }) { // const { data } = arr // 我们只要 data 数据 // 内部处理 console.log(data) } render(msg) // 需求3, 为了防止msg里面的data名字混淆,要求渲染函数里面的数据名改为 myData function render({ data: myData }) { // 要求将 获取过来的 data数据 更名为 myData // 内部处理 console.log(myData) } render(msg) </script> </body> </html>
遍历数组 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>Document</title> </head> <body> <script> // forEach 就是遍历 加强版的for循环 适合于遍历数组对象 const arr = ['red', 'green', 'pink'] const result = arr.forEach(function (item, index) { console.log(item) // 数组元素 red green pink console.log(index) // 索引号 }) // console.log(result) </script> </body> </html>
使用箭头函数、对象结构、数组的forEach函数共同完成功能
四、综合案例
关键代码:
<script> // 2. 初始化数据 const goodsList = [ { id: '4001172', name: '称心如意手摇咖啡磨豆机咖啡豆研磨机', price: '289.00', picture: 'https://yanxuan-item.nosdn.127.net/84a59ff9c58a77032564e61f716846d6.jpg', }, { id: '4001594', name: '日式黑陶功夫茶组双侧把茶具礼盒装', price: '288.00', picture: 'https://yanxuan-item.nosdn.127.net/3346b7b92f9563c7a7e24c7ead883f18.jpg', }, { id: '4001009', name: '竹制干泡茶盘正方形沥水茶台品茶盘', price: '109.00', picture: 'https://yanxuan-item.nosdn.127.net/2d942d6bc94f1e230763e1a5a3b379e1.png', }, { id: '4001874', name: '古法温酒汝瓷酒具套装白酒杯莲花温酒器', price: '488.00', picture: 'https://yanxuan-item.nosdn.127.net/44e51622800e4fceb6bee8e616da85fd.png', }, { id: '4001649', name: '大师监制龙泉青瓷茶叶罐', price: '139.00', picture: 'https://yanxuan-item.nosdn.127.net/4356c9fc150753775fe56b465314f1eb.png', }, { id: '3997185', name: '与众不同的口感汝瓷白酒杯套组1壶4杯', price: '108.00', picture: 'https://yanxuan-item.nosdn.127.net/8e21c794dfd3a4e8573273ddae50bce2.jpg', }, { id: '3997403', name: '手工吹制更厚实白酒杯壶套装6壶6杯', price: '100.00', picture: 'https://yanxuan-item.nosdn.127.net/af2371a65f60bce152a61fc22745ff3f.jpg', }, { id: '3998274', name: '德国百年工艺高端水晶玻璃红酒杯2支装', price: '139.00', picture: 'https://yanxuan-item.nosdn.127.net/8896b897b3ec6639bbd1134d66b9715c.jpg', }, ] // 1. 渲染函数 封装 function render(arr) { // 声明空字符串 let str = '' // 遍历数组 arr.forEach(item => { // 解构 const { name, picture, price } = item str += ` <div class="item"> <img src=${picture} alt=""> <p class="name">${name}</p> <p class="price">${price}</p> </div> ` }) // 追加给list document.querySelector('.list').innerHTML = str } render(goodsList) // 页面一打开就需要渲染 // 2. 过滤筛选 document.querySelector('.filter').addEventListener('click', e => { // e.target.dataset.index e.target.tagName const { tagName, dataset } = e.target // 判断 if (tagName === 'A') { // console.log(11) // arr 返回的新数组 let arr = goodsList if (dataset.index === '1') { arr = goodsList.filter(item => item.price > 0 && item.price <= 100) } else if (dataset.index === '2') { arr = goodsList.filter(item => item.price >= 100 && item.price <= 300) } else if (dataset.index === '3') { arr = goodsList.filter(item => item.price >= 300) } // 渲染函数 render(arr) } }) </script>