系列文章目录
前言
这是一篇JavaScript进阶文章,内容详细,适合面试人员,学习提升相关笔记,希望对你有所帮助。
1️⃣作用域
2️⃣函数进阶
3️⃣解构赋值
4️⃣综合案例
一、作用域 😈
1.掌握作用域等概念加深对JS理解
2.学习ES6新特性让代码书写更加简洁便利
目标:了解作用域对程序执行的影响及作用域链的查找机制,使用闭包函数创建隔离作用域避免全局变量污染作用域(scope)规定了变量能够被访问的“范围”,离开了这个“范围”变量便不能被访问,
作用域分为:
局部作用域
全局作用域
1.1 局部作用域
局部作用域分为函数作用域和块作用域。
1.1.1函数作用域:
在函数内部声明的变量只能在函数内部被访问,外部无法直接访问。
<script>
function getSum() {
//函数内部是函数作用域属于局部变量
const num = 10
}
console.log(num)//此处报错函数外部不能使用局部作用域变量
</script>
1.1.2总结:
1.函数内部声明的变量,在函数外部无法被访问
2.函数的参数也是函数内部的局部变量
3.不同函数内部声明的变量无法互相访问
4.函数执行完毕后,函数内部的变量实际被清空了
1. 2.1 块作用域
在JavaScript 中使用{}包裹的代码称为代码块,代码块内部声明的变量外部将【有可能
】无法被访问。
for (let t = 1; t<= 6; t++) {
// t只能在该代码块中被访问
console.log(t)//正常
}
//超出了t的作用域
console.log(t)//报错
1.2.2总结
1.let声明的变量会产生块作用域,var不会产生块作用域
2.const声明的常量也会产生块作用域
3.不同代码块之间的变量无法互相访问
4.推荐使用let或const
1.2总结
1.局部作用域分为哪两种?
函数作用域 函数内部
块级作用域 { }
2.局部作用域声明的变量外部能使用吗?
不能
1.3全局作用域
< script>标签和.js文件的【最外层】就是所谓的全局作用域,在此声明的变量在函数内部也可以被访问。全局作用域中声明的变量,任何其它作用域都可以被访问
< script>
//全局作用域
//全局作用域下声明了num变量const num = 10
function fn() {
//函数内部可以使用全局作用域的变量
console.log(num)
}
//此处全局作用域
</ script>
1.3.1注意:
1.为 window对象动态添加的属性默认也是全局的,不推荐!
2.函数中未使用任何关键字声明的变量为全局变量,不推荐!!!
3.尽可能少的声明全局变量,防止全局变量被污染
1.全局作用域有哪些?
< script>标签内部
.js 文件
2.全局作用域声明的变量其他作用域能使用吗?
相当能
1.4思考题
1.代码有错误吗?如果没有错误结果是几?
1.代码有错误吗?如果没有错误结果是几?
<script>
//全局作用域
let a = 1
let b = 2
//局部作用域
function f() {
let a = 1
//局部作用域
function g() {
a = 2
console.log( a)
}
g()//调用g
}
f()//调用f
</ script>
1.5作用域链😈
作用域链本质上是底层的变量查找机制。
在函数被执行时,会
优先查找当前
函数作用域中查找变量
如果当前作用域查找不到则会依次逐级查找父级作用域
直到全局作用域
1.5.1总结:
1.嵌套关系的作用域串联起来形成了作用域链
2.相同作用域链中按着从小到大的规则查找变量
3.子作用域能够访问父作用域,父级作用域无法访问子级作用域( f 并不能访问g)
1.作用域链本质是什么?
作用域链本质上是底层的变量查找机制
2.作用域链查找的规则是什么?
会优先查找当前函数作用域中查找变量
查找不到则会依次逐级查找父级作用域直到全局作用域
1.6 JS垃圾回收机制闭包😈
目标:了解JS垃圾回收机制的执行过程学习
目的:为了闭包做铺垫
学习路径:
1.什么是垃圾回收机制
2.内存的声明周期
3.垃圾回收的算法说明
1.6.1什么是垃圾回收机制?
垃圾回收机制(Garbage collection)简称GC
JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾回收器自动回收。正因为垃圾回收器的存在,许多人认为JS不用太关心内存管理的问题
但如果不了解JS的内存管理机制,我们同样非常容易成内存泄漏(内存无法被回收)的情况不再用到的内存,没有及时释放,就叫做内存泄漏
1.6.2 内存的声明周期
JS环境中分配的内存,一般有如下生命周期:
1.内存分配:当我们声明变量、函数、对象的时候,系统会自动为他们分配内存
2.内存使用:即读写内存,也就是使用变量、函数等
3.内存回收:使用完毕,由垃圾回收自动回收不再使用的内存
4.说明:
全局变量一般不会回收 (关闭页面回收)
一般情况下局部变量的值,不用了,会被自动回收掉
//为变量分配内存
const i = 11
const str = 'pink老师' //为对象分配内存
const person = {
age:18,
name:'pink老师·}
//为函数分配内存
function sum(a,b){
return a + b
}
1.6.3 总结
1.什么是垃圾回收机制?
简称GC
JS中内存的分配和回收都是自动完成的,内存在不使用的时候会被垃圾
回收器自动回收
2.什么是内存泄漏?
不再用到的内存,没有及时释放,就叫做内存泄漏
3.内存的声明周期是什么样的?
内存分配、内存使用、内存回收
全局变量一般不会回收;一般情况下局部变量的值,不用了,会被自动回动收掉
1.6.4 垃圾回收算法说明
所谓垃圾回收,核心思想就是如何判断内存是否已经不再会被使用了,如果是,就视为垃圾,释放掉下面介绍两种常见的浏览器垃圾回收算法:引用计数法
和标记清除法
- 引用计数
IE采用的引用计数算法,定义“内存不再使用”的标准很简单,就是看一个对象是否有指向它的引用。
算法:
1.跟踪记录每个值被引用的次数。
2.如果这个值的被引用了一次,那么就记录次数1
3.多次引用会累加。
4.如果减少一个引用就减1。
5.如果引用次数是0,则释放内存。
const person ={
age: 18,
name: 'pink老师'
}
const p = person
person = 1
p = null
function fn(){
let o1 = l
let o2= 0
o1.a = o2
o2.a = o1
return '引用计数无法回收'
}
fn()
因为他们的引用次数永远不会是0。这样的相互引用如果说很大量的存在就会导致大量的内存泄露
- ·标记清除法
现代的浏览器已经不再使用引用计数算法了。
现代浏览器通用的大多是基于标记清除算法的某些改进算法,总体思想都是一致的。
核心:
1.标记清除算法将“不再使用的对象”定义为“无法达到的对象”。
2.就是从根部(在JS中就是全局对象)出发定时扫描内存中的对象。凡是能从根部到达的对象,都是还需要使用的。
3.那些无法由根部出发触及到的对象被标记为不再使用,稍后进行回收。
function fn(){
let o1 = l
let o2= 0
o1.a = o2
o2.a = o1
return '引用计数无法回收'
}
fn()
这样就可以消除内存泄漏。
1.7 闭包💜
目标:能说出什么是闭包,闭包的作用以及注意事项
概念:一个函数对周围状态的引用捆绑在一起,内层函数中访问到其外层函数的作用域简单理解。
闭包=内层函数+外层函数的变量
function outer() {
const a = 1
function f() {
console.log(a)
}
f()
}
outer()
闭包作用:封闭数据,提供操作,外部函数也可以访问函数内部的变量
闭包的基本格式:
function outer() {
let i = 1
function fn() {
console.log(i)
}
return fn
}
const fun = outer()
fun()
//外层函数使用内部函数的变量
写法一:
写法二:
写法三:
1.7.1 闭包的应用及问题
- 统计函数被调用的次数
- 闭包应用:实现数据的私有
比如,我们要做个统计函数调用次数,函数调用一次,就++
因为变量是全局变量,容易被修改,所以用闭包形式将变量封装,实现数据私有。
let count = 1
function fn() {
count++
console.log(函数被调用${ count}次`)
}
fn()// 2
fn()//3
但是,这个count是个全局变量,很容易被修改
//闭包形式统计函数调用的次数
function fn() {
let count = 1
function fun() {
count++
console.log(`函数被调用${ count}次)
}
return fun
}
const result = fn()
result() // 2
result()// 3
这样实现了数据私有,无法直接修改count
1.7.2 总结
1.怎么理解闭包?
闭包=内层函数+外层函数的变量
2.闭包的作用?
封闭数据,实现数据私有,外部也可以访问函数内部的变量 闭包很有用,
因为它允许将函数与其所操作的某些数据(环境)关联起来
3.闭包可能引起的问题?
内存泄漏
1.8 变量提升
-
目标:了解什么是变量提升
变量提升是JavaScript中比较“奇怪”的现象,它允许在变量声明之前即被访问(仅存在于var声明变量
)
JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6引入了块级作用域,用let或者const声明变量,让代码写法更加规范和人性化。 -
注意:
1.变量在未声明即被访问时会报语法错误
2.变量在var声明之前即被访问,变量的值为undefined
3.let/const声明的变量不存在变量提升
4.变量提升出现在相同作用域当中
5.实际开发中推荐先声明再访问变量
1.8.1 总结
1.用哪个关键字声明变量会有变量提升?
var
2.变量提升是什么流程?
- 先把var变量提升到当前作用域于最前面
- 只提升变量声明,不提升变量赋值
- 然后依次执行代码
我们不建议使用var声明变量
二、函数进阶
2.1 函数提升
目标:能说出函数提升的过程
函数提升与变量提升比较类似,是指函数在声明之前即可被调用。
1.会把所有函数声明提升到当前作用域的最前面
2.只提升函数声明,不提升函数调用
//调用函数
foo()
//声明函数
function foo(){
console.log('声明之前即被调用... ')
}
函数表达式赋值不存在提升的现象
//不存在提升现象
bar()//错误
var bar = function (){
console.log('函数表达式不存在提升现象...")
}
总结:
1.函数提升能够使函数的声明调用更灵活
2.函数表达式赋值不存在提升的现象(例如 var bar=…)
3.函数提升出现在相同作用域当中
2.2 函数参数
知道函数参数默认值、动态参数、剩余参数的使用细节,提升函数应用的灵活度,知道箭头函数的语法及与普通函数的差异。
函数参数的使用细节,能够提升函数应用的灵活度。
学习路径:
1.动态参数
2.剩余参数
2.2.1.动态参数
产品需求:写一个求和函数
getSum(2,3)
getsum(1,23)
getSum(1,2,3,4,5,6)
不管用户传入几个实参,都要把和求出来
arguments是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参
//求生函数,计算所有参数的和
function sum() {
// arguments 动态参数 只存在 函数里面
//伪数组
console.log( arguments)
let s = 0
for(let i = o; i < arguments.length; i++){
s += arguments[i]
console.log(s)
}
//调用求和函数
sum(5,10)//两个参数sum(1,2,4)1/两个参数
2.2.2 总结:
- arguments是一个伪数组,只存在于函数中
- arguments的作用是动态获取函数的实参
- 可以通过for循环依次得到传递过来的实参
1.当不确定传递多少个实参的时候,我们怎么办?
arguments动态参数
- arguments是什么?
伪数组
它只存在函数中
2.2.3 剩余参数
目标:能够使用剩余参数
剩余参数允许我们将一个不定数量的参数表示为一个数组
function getSum( ...other) {
// other得到[1,2,3]
console.log(other)
}
getsum(1,2,3)
function getSum(a, b, ...arr) {
console.log(arr)
}
getSum(2,3)
getSum(1,2,3,4,,5)
1…是语法符号,置于最末函数形参之前,用于获取多余的实参
⒉.借助…获取的剩余实参,是个真数组
开发中,还是提倡多使用剩余参数。
1.剩余参数主要的使用场景是?
用于获取多余的实参
2.剩余参数和动态参数区别是什么?开发中提倡使用哪一个?
动态参数是伪数组
剩余参数是真数组
开发中使用剩余参数想必也是极好的
2.3 展开运算符
目标:能够使用展开运算符并说出常用的使用场景
展开运算符(…),将一个数组进行展开
const arr = [1,5,3,8,2]
console.log( ...arr)// 1 5 3 8 2
说明:
1.不会修改原数组
典型运用场景:求数组最大值(最小值)、合并数组等
const arr = [1,2,3]
//展开运算符可以展开数组
//console.Log( . . .arr)
console.Log(Math.max(1,2,3))
console.log(Math.max(...arr))// 3
const arr1 =[1,2,3]//展开运算符可以展开数组
//consoLe.Log(...arr)
//consoLe.Log (Math.max(1,2,3))
// ...arr1 === 1,2,3
// 1求数组最大值
console.log(Math.max(...arr1))//3
console.log(Math.min( . . .arr1))// 1
//2.合并数组
const arr2 =[3,4,5]
const arr = [...arr1, ...arr2]
console.log(arr)
2. 3.1总结
展开运算符or剩余参数
剩余参数: 函数参数使用,得到真数组
展开运算符:数组中使用,数组展开
1.展开运算符主要的作用是?
可以把数组展开,可以利用求数组最大值以及合并数组等操作
2.展开运算符和剩余参数有什么区别?
展开运算符主要是数组展开
剩余参数在函数内部使用
2.4 箭头函数(重要)
目标:能够熟悉箭头函数不同写法
目的:引入箭头函数的目的是更简短的函数写法并且不绑定this,箭头函数的语法比函数表达式更简洁
使用场景:箭头函数更适用于那些本来需要匿名函数的地方
学习路径:
1.基本语法
2.箭头函数参数
3.箭头函数this
2.4.1 基本语法
//1.箭头函数基本语法
const fn = ()=>{
consoLe.Log(123)
}
fn()
const fn =(×)=>{
consoLe.Log(x)
}
fn(1)
// 2.只有一个形参的时候,可以省略小括号
const fn = x =>{
console.log(x)}
fn(1)
// 3. 代码只有一行 大括号可以省略
const fn = × =>console.log(×)
fn(1)
//4.如果函数体只有一行代码,可以写到一行上,并且无需写return直接返回值
const fn = (x,y)=> x+y
console.log(fn(1,2))// 3
//5 :加括号的函数体返回对象字面量表达式
//({大括号冲突,中括号区分})
const fn = ( uname) =>({ name: uname })
fn( '刘德华')
2.4.2总结
1.箭头函数属于表达式函数,因此不存在函数提升
2.箭头函数只有一个参数时可以省略圆括号()
3.箭头函数函数体只有一行代码时可以省略花括号0,并自动做为返回值被返回
4.加括号的函数体返回对象字面量表达式
2.4.3 箭头函数参数
1.普通函数有arguments动态参数
2.箭头函数没有arguments动态参数,但是有剩余参数…args
//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)
2.4.4 总结
1.箭头函数里面有arguments动态参数吗?可以使用什么参数?
没有arguments动态参数
可以使用剩余参数(…args)
2.4.5 箭头函数this
在箭头函数出现之前,每一个新函数根据它是被如何调用的来定义这个函数的this值,非常令人讨厌。
console.log(this)//此处为window
const sayHi = function ) {
console.1og(this)//普通函数指向调用者此处为window
btn.addEventListener( 'click ', function ()
{
console.log(this)
//当前this指向 btn
}
// 2.箭头函数的this
const fn = () => {
console.log(this)// window
}
fn()
// 3. 对象函数指向 window
const user = {
name: '小明',
//该箭头函数中的this 为函数声明环境中this一致
walk: ()=>{
console.log(this) // 指向window不是user
}
}
user. walk()
箭头函数不会创建自己的this,
它只会从自己的作用域链的上一层沿用this。
const user = {
name: '小明',
sleep: function () {
console.log(this)//指向user
const fn = ()=>{
console.log(this)//指向user该箭头函数中的 this 与 sLeep中的 this 一致}
//调用箭头函数
fn()
}
user.sleep()
2.4.6 总结
1.箭头函数里面有this吗?
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层沿用this
2.DOM事件回调函数推荐使用箭头函数吗?
不太推荐,特别是需要用到this的时候
事件回调函数使用箭头函数时,this为全局的window
三、解构赋值
目标:知道解构的语法及分类,使用解构简洁语法快速为变量赋值
const arr = [ 100,60,80]
console.log( arr[e])//最大值
console.log( arr[1])//最小值
console.log(arr[2])//平均值
3.1.数组解构
数组解构是将数组的单元值快速批量赋值
给一系列变量的简洁语法。
基本语法:
1.赋值运算符=左侧的[ ] 用于批量声明变量,右侧数组的单元值将被赋值给左侧的变量
2.变量的顺序对应数组单元值的位置依次进行赋值操作
//同时将数组单元值1 23 依次赋值给变量a b c
const [a, b, c] =[1,2,3]
console.log(a)//1
console.log(b)// 2
console.log(c)// 3
基本语法:典型应用交互2个变量
补充💜-- js必须加分号的两种情况
数组解构是将数组的单元值快速批量赋值给一系列变量的简洁语法。
基本语法:典型应用交互2个变量
3.1.1.立即执行函数
( function t() { })();
//或者
; (function t() { })()
3.1.2.数组解构
[数组开头的,特别是前面有语句的一定注意加分号
;[b, a] = [a, b]
//1.立即执行函数要加
(function () { })();
(function () { })();
//2.使用数组的时候
/const arr = [1,2,3]
const str = 'pink ';
[1,2,3].map(function (item){
console.log(item)
})
let a = 1
let b = 2
; [b,a] = [a, b]
console.log(a, b)
3.1.3 总结
1.数组解构赋值的作用是什么?
是将数组的单元值快速批量赋值给一系列变量的简洁语法
2.Js 前面有两哪种情况需要加分号的?
立即执行函数
数组解构
3.1.4数组解构变量和单元值数量
1.变量多单元值少的情况:
// 1.变量多,单元值少
const [a, b, c,d] = ['小米','苹果','华为']
console.log(a)//小米
console.log(b)//苹果
console.log(c)//华为
console.log(d)//undefined
2.变量少单元值多的情况:
//变量少,单元值多
const [a, b, c]=['小米','苹果','华为','格力']
console.log(a)//小米
console.log(b)//苹果
console.log(c)//华为
3.利用剩余参数解决变量少单元值多的情况:
//利用剩余参数变量少,单元值多
const [a, b, ...tel] =['小米',‘苹果',‘华为',‘格力', 'vivo']
console.log(a)/小米
console.log(b)//苹果
console.log(tel)// ['华为',‘格力',‘vivo ']
4.防止有undefined传递单元值的情况,可以设置默认值:
const [a ='手机',b ='华为]=['小米']
console.log(a) //小米
console.log(b) //华为
5.按需导入赋值
const [a, b, , d] = [1,2,3,4]
console.log(a) // 1
console.log(b)// 2
console.log(d) //4
6 .多维数组解构
1.变量的数量大于单元值数量时,多余的变量将被赋值为?
undefined
2.变量的数量小于单元值数量时,可以通过什么剩余获取所有的值?
剩余参数…获取剩余单元值,但只能置于最末位
const [a,b]=['苹果',['小米','华为']]
console.log(a)//苹果
console.log(b)//['小米','华为']
3.1.5 独立完成数组解构赋值
需求① : 有个数组: const pc =[‘海尔’,‘联想’,‘小米’,‘方正’]结构为变量: hr lx mi fz
需求② : 请将最大值和最小值函数返回值解构max和min两个变量
function getValue() {
return [ 100,60]
}
//要求max变量里面存100min变量里面存60
const [max, min]=getValue();
console.log(max);
console.log(min);
3.2. 对象解构
对象解构是将对象属性
和方法快速批量赋值
给一系列变量的简洁语法
基本语法:
1.赋值运算符=左侧的0用于批量声明变量,右侧对象的属性值将被赋值给左侧的变量
2.对象属性的值将被赋值给与属性名相同的变量(等号两边属性名
)
3.注意解构的变量名不要和外面的变量名冲突否则报错
4.对象中找不到与变量名一致的属性时变量值为undefined
<script>
//普通对象
const user = {
name: '小明",age: 18
}
//批量声明变量name age
//同时将数组单元值小明 18 依次赋值给变量nameage
const {name,age} = user
console.log( name)//小明
console.log(age)// 18
</script>
3.2.1 对象解构变量重新命名
旧变量名 : 新变量名
/对象解构的变量名可以重新改名旧变量名:新变量名
const { uname: username,age } = {
uname: 'pink老师',age: 18
}
console.log(username)
console.log(age)
3.2.2 解析数组对象
const pig =[{
uname:'佩奇',
age: 6
}
]
const [{ uname,age }]= pigconsole.log(uname)
console.log(age)
3.2.3 独立完成对象解构赋值
需求①: 有个对象 : const pig = { name: ‘佩奇’,age: 6 } 结构为变量:完成对象解构,并以此打印出值
需求②: 请将pig对象中的name,通过对象解构的形式改为uname,并打印输出
需求③:请将数组对象,完成商品名和价格的解构
const goods = [
{
goodsName: '小米',
price: 1999
]
3.2.4 多级对象解构
const pig = {
name: '佩奇',
family: {
mother: '猪妈妈',
father: '猪爸爸',
sister: '乔治',
age: 6
}
const [{ name, family: { mother,father,sister }}]= person
console.log( name)
console.log ( mother)
console.log(father)
console.log(sister)
3.2.5 多级对象解构案例
//这是后台传递过来的数据,请选出data里面的数据方便后面渲染w
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
function render(arr){
//我们只要data数据
//内部处理
console.log(arr)
}
render(data)
//需求3,为了防山msg里面的data名字混淆,要求渲染函数里面的数据名改为myData
function render({data:mydata}){
//要求将获取过来的data数据更名为 myData
//内部处理
console.log(mydata)
}
render(msg)
forEach遍历数组
forEach() 方法
用于调用数组的每个元素,并将元素传递给回调函数主要使用场景:遍历数组的每个元素
语法:
被遍历的数组.forEach(function(当前数组元素,当前元素索引号){
//函数体
})
列如:
const arr = [ 'pink ', 'red' , 'green ' ]
arr.forEach(function (item,index) {
console.log(当前数组元素是: ${item} )//依次打印数组每一个元素
console.log(`当前数组元素的索引是:${index} )//依次打印数组每一个元素的索引})
forEach()方法用于调用数组的每个元素,并将元素传递给回调函数
被遍历的数组.forEach(function(当前数组元素,当前元素索引号){
//函数体
})
注意:
- forEach主要是遍历数组
- 参数当前数组元素是必须要写的,索引号可选。
四、综合案例
<div class="list">
<div cLass="item">
<img src="" aLt=""><p class="name "></p>
<p class="price"></p>
</div>
</div>
<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: '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',
},
]
</script>
渲染商品列表案例
核心思路:有多少条数据,就渲染多少模块,然后生成对应的 html结构标签,赋值给list标签即可
①:利用forEach遍历数据里面的数据
②:拿到数据,利用字符串拼接
生成结构添加到页面中
③:注意:传递参数的时候,可以使用对象解构
//声明一个字符串变量
let str = ''
// 遍历函数
goodsList.forEach(item =>{
// console.Log(item)
//可以得到每一个数组元素对象{id: '4001172 '}
//const {id} = item对象解构
const {picture,name,price} =item
str +=`
<div class="item">
<img src="${picture}" alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
document.querySelector('.list').innerHTML = str
商品列表价格筛选
需求:
①:渲染数据列表
②:根据选择不同条件显示不同商品
筛选数组filter方法(重点)
filter()方法创建一个新的数组,新数组中的元素是通过检查指定数组中符合条件的所有元素主要使用场景:筛选数组符合条件的元素,并返回筛选之后元素的新数组
语法:
被遍历的数组.filter(function (currentVaLue, index) {
return筛选条件
})
例:
箭选数组中大于30的元素
const score = [10,50,3,40,33]
const re = score.filter(function (item) {
return item > 30
})
console.log(re)//[50,40,33]
- filter()筛选数组
- 返回值:返回数组,包含了符合条件的所有元素。如果没有符合条件的元素则返
- 空数组参数:currentValue必须写,index可选
- 因为返回新数组,所以不会影响原数组
步骤:
②:点击不同需求,显示不同页面内容
(1)点击采取事件委托方式@.filter
(2)利用过滤函数filter筛选出符合条件的数据,因为生成的是一个数组,传递给渲染函数即可
(3)筛选条件是根据点击的data-index来判断
(4)可以使用对象解构,把事件对象解构
(5)因为全部区间不需要筛选,直接把goodList渲染即可
function render(arr){
//声明一个字符串变量
let str = ''
// 遍历函数
arr.forEach(item =>{
// console.Log(item)
//可以得到每一个数组元素对象{id: '4001172 '}
//const {id} = item对象解构
const {picture,name,price} =item
if(price>30){
}
str +=`
<div class="item">
<img src="${picture}" alt="">
<p class="name">${name}</p>
<p class="price">${price}</p>
</div>
`
})
document.querySelector('.list').innerHTML = str
}
render(goodsList)//页面打开需要渲染
// 2. 过滤
document.querySelector('.filter').addEventListener('click',e =>{
// console.log(e.target.dataset)
const {tagName,dataset} =e.target
let arr= goodsList// 一打开页面,还没选者区间,先加载全部内容
if(tagName == 'A'){
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)
}
})
总结
以上就是作用域,函数进阶,解构赋值,综合案例全部内容,还会持续更新❤️。