目录
1.作用域
1.1 局部作用域
1.2 全局作用域
1.3 作用域链
1.4 JS垃圾回收机制
1.4.1 什么是垃圾回收机制?
1.4.2 内存的生命周期
1.4.3 算法说明
1.5 闭包
1.6 变量提升
2.函数进阶
2.1 函数提升
2.2 函数参数
2.2.1 动态参数
2.2.2 剩余参数
2.2.3 展开运算符
2.3 箭头函数
2.3.1 基本语法
2.3.2 箭头函数参数
2.3.3 箭头函数this
3.解构赋值
3.1 数组解构
3.1.1 基本语法
3.1.2 数组解构可能带来的问题
3.2 对象解构
3.2.1 基本语法
3.2.2 对象解构的一些操作
3.2.3 遍历数组 forEach 方法(重点)
3.2.4 筛选数组 filter 方法(重点)
4.综合案例
1.作用域
- Ø 局部作用域
- Ø 全局作用域
1.1 局部作用域
- 1. 函数内部声明的变量,在函数外部无法被访问
- 2. 函数的参数也是函数内部的局部变量
- 3. 不同函数内部声明的变量无法互相访问
- 4. 函数执行完毕后,函数内部的变量实际被清空了(垃圾回收机制)
- 1. let 声明的变量会产生块作用域{ },var 不会产生块作用域,而是产生全局作用域
- 2. const 声明的常量也会产生块作用域
- 3. 不同代码块之间的变量无法互相访问
- 4. 推荐使用 let 或 const
1.2 全局作用域
- 1. 为 window 对象动态添加的属性默认也是全局的,不推荐!
- 2. 函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
- 3. 尽可能少的声明全局变量,防止全局变量被污染(立即执行函数)
1.3 作用域链
- Ø 在函数被执行时,会优先查找当前函数作用域中查找变量
- Ø 如果当前作用域查找不到则会依次逐级查找父级作用域直到全局作用域
执行流程:
- 1. 嵌套关系的作用域串联起来形成了作用域链
- 2. 相同作用域链中按着从小到大的规则查找变量
- 3. 子作用域能够访问父作用域,父级作用域无法访问子级作用域
1.4 JS垃圾回收机制
1.4.1 什么是垃圾回收机制?
1.4.2 内存的生命周期
- 1. 内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
- 2. 内存使用:即读写内存,也就是使用变量、函数等
- 3. 内存回收:使用完毕,由垃圾回收自动回收不再使用的内存
- 4. 说明:
- Ø 全局变量一般不会回收(关闭页面回收);
- Ø 一般情况下局部变量的值, 不用了, 会被自动回收掉
1.4.3 算法说明
- 1. 栈(操作系统): 由操作系统自动分配释放函数的参数值、局部变量等,基本数据类型放到栈里面。
- 2. 堆(操作系统): 一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。复杂数据类型放到堆里面。
引用计数法
- 1. 跟踪记录被引用的次数
- 2. 如果被引用了一次,那么就记录次数1,多次引用会累加 ++
- 3. 如果减少一个引用就减1 --
- 4. 如果引用次数是0 ,则释放内存
这里还存在引用次数就不会被回收
这里没有了引用次数就会被回收
问题:
标记清除法
- 1. 标记清除算法将“不再使用的对象”定义为“无法达到的对象”。
- 2. 就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象。 凡是能从根部到达的对象,都是还需要使用的。从根部找到后,只要根部里面的函数局部变量需要用到,也不会被回收。
- 3. 那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。
标记所有的引用
1.5 闭包
实现数据私有。
缺点:可能出现内存泄漏。
1.6 变量提升
- 1. 变量在未声明即被访问时会报语法错误
- 2. 变量在var声明之前即被访问,变量的值为 undefined,存在变量提升
- 3. let/const 声明的变量不存在变量提升
- 4. 变量提升出现在当前作用域中
- 5. 实际开发中推荐先声明再访问变量
2.函数进阶
2.1 函数提升
函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
- 1. 函数提升能够使函数的声明调用更灵活
- 2. 函数表达式不存在提升的现象
- 3. 函数提升出现在相同(当前)作用域当中
2.2 函数参数
- 1. 动态参数
- 2. 剩余参数
2.2.1 动态参数
2.2.2 剩余参数
得到的是一个真数组
剩余参数获取到的参数更加灵活。
2.2.3 展开运算符
剩余参数和展开运算符的比较:
2.3 箭头函数
学下箭头函数先再复习一下之前的有关函数的知识:
下面是几种常见的函数样式,包括函数声明、函数表达式、箭头函数等:
-
函数声明(Function Declaration):
function greet(name) { return `Hello, ${name}!`; }
- 这种方式定义的函数在代码执行之前已经存在,可以在定义之前调用。
-
函数表达式(Function Expression):
const greet = function(name) { return `Hello, ${name}!`; };
- 函数表达式将函数赋值给一个变量,这种函数只能在定义之后调用。
-
箭头函数(Arrow Function):
const greet = (name) => { return `Hello, ${name}!`; };
- 箭头函数是函数表达式的一种简写形式,不具有自己的
this
、arguments
、super
或new.target
。
- 箭头函数是函数表达式的一种简写形式,不具有自己的
-
立即调用函数表达式(IIFE, Immediately Invoked Function Expression):
(function() { console.log('This function runs immediately.'); })();
- IIFE 是一种自执行的函数表达式,用于创建一个独立的作用域。
-
方法定义(Method Definition):
const person = { name: 'John', greet() { return `Hello, ${this.name}!`; } };
- 在对象中定义的方法可以直接使用简写语法。
- 1. 基本语法
- 2. 箭头函数参数
- 3. 箭头函数this
2.3.1 基本语法
2.3.2 箭头函数参数
2.3.3 箭头函数this
3.解构赋值
3.1 数组解构
数组解构的了解:
3.1.1 基本语法
- 1. 赋值运算符 = 左侧的 [ ] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
- 2. 变量的顺序对应数组单元值的位置依次进行赋值操作
案例:
<body>
<!-- 需求①: 有个数组: const pc = ['海尔', '联想', '小米', '方正']
解构为变量: hr lx mi fz
需求②:请将最大值和最小值函数返回值解构 max 和min 两个变量 -->
<script>
const [hr, lx, mi, fz] = ['海尔', '联想', '小米', '方正']
console.log(hr)
function fn(x, y) {
return [x, y]
}
const [max, min] = fn(20, 10)
console.log(max)
console.log(min)
</script>
</body>
3.1.2 数组解构可能带来的问题
3.2 对象解构
3.2.1 基本语法
- 1. 赋值运算符 = 左侧的 {} 用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
- 2. 对象属性的值将被赋值给与属性名相同的变量
- 3. 注意解构的变量名不要和外面的变量名冲突否则报错
- 4.对象中找不到与变量名一致的属性时变量值为 undefined
3.2.2 对象解构的一些操作
<script>
// 需求①: 有个对象: const pig = { name: '佩奇',age: 6 }
const { name, age } = { name: '佩奇', age: 6 }
console.log(name, age)
// 需求②:请将pig对象中的name,通过对象解构的形式改为 uname,并打印输出
const { name: uname, age: ages } = { name: '佩奇', age: 6 }
console.log(uname)
// 需求③:请将 数组对象, 完成 商品名和价格的解构
const goods = [
{
goodsName: '小米',
price: 1999
}
]
const [{ goodsName, price }] = goods
console.log(goodsName, price)
</script>
3.多级对象解构:
只获取msg里面的data数据。
<script>
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: '99.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',
},
]
// 有多少个对象,就生成多少个div
// <!-- <div class="item">
// <img src="" alt="">
// <p class="name"></p>
// <p class="price"></p>
// </div> -->
let str = ''
const list = document.querySelector('.list')
goodsList.forEach((e) => {
const { name, price, picture } = e
str += `
<div class="item">
<img src="${picture}" alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
list.innerHTML = str
</script>
3.2.3 遍历数组 forEach 方法(重点)
- 1. forEach 主要是遍历数组
- 2. 参数当前数组元素是必须要写的, 索引号可选。
- 3.跟map有些类似,但是不返回新数组
案例:
<script>
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: '99.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',
},
]
// 有多少个对象,就生成多少个div
// <!-- <div class="item">
// <img src="" alt="">
// <p class="name"></p>
// <p class="price"></p>
// </div> -->
let str = ''
const list = document.querySelector('.list')
goodsList.forEach((e) => {
const { name, price, picture } = e
str += `
<div class="item">
<img src="${picture}" alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
list.innerHTML = str
</script>
3.2.4 筛选数组 filter 方法(重点)
4.综合案例
实现效果:
<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>