当前位置: 首页 > news >正文

JavaScript-作用域、函数进阶、解构赋值、filter详解

一、作用域

• 局部作用域

• 全局作用域

• 作用域链

• JS垃圾回收机制

• 闭包

• 变量提升 

1. 作用域

⑴ 局部作用域

2.全局作用域

3. 作用域链

就近原则:输出为2

4.JS垃圾回收机制

⑴. 什么是垃圾回收机制?

⑵.内存的生命周期

⑶.拓展-JS垃圾回收机制-算法说明

①引用计数

但它却存在一个致命的问题:嵌套引用(循环引用)

这两个对象都有指向它的引用,即便let o1=null,  let o2 =null ,依旧存在一个指向它的引用:o1.a=02, o2.a=01

②标记清除法

5. 闭包

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <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()
    </script>

</body>

</html>

闭包作用:封闭数据,提供操作,外部也可以访问函数内部的变量

闭包的基本格式:

闭包应用:实现数据的私有

代码逻辑概述

此代码定义了一个外部函数 count,该函数内部定义了一个变量 i 和一个内部函数 fnfn 函数会让 i 的值加 1,并且输出当前函数被调用的次数。最后,count 函数返回 fn 函数。当你调用 count() 并把返回值赋给 fun 时,fun 就变成了 fn 函数,并且能持续追踪 i 的值。

内存泄漏原因

在 JavaScript 里,闭包是指有权访问另一个函数作用域中的变量的函数。在这个例子中,fn 函数形成了一个闭包,它能够访问 count 函数作用域中的 i 变量。由于 fun 引用了 fn 函数,fn 函数又引用了 count 函数作用域中的 i 变量,这就导致 count 函数执行完毕之后,其作用域不会被销毁,i 变量也会一直存在于内存中。

若这个闭包(也就是 fun)在整个应用的生命周期内一直存在,那么 i 变量就会一直占用内存,无法被垃圾回收机制回收。要是在程序里大量使用这类闭包,或者闭包持有了大量的数据,就会造成内存占用不断增加,最终可能引发内存泄漏。

示例代码

下面是一段示例代码,用来展示闭包造成的内存占用情况:

function count() {
    let i = 0;
    function fn() {
        i++;
        console.log(`函数被调用了${i}次`);
    }
    return fn;
}

const fun = count();
fun(); // 输出: 函数被调用了1次
fun(); // 输出: 函数被调用了2次
// 这里即使不再需要 fun 函数,它所引用的 i 变量依然占用内存

解决方案

若你想避免这种内存泄漏问题,在不再需要闭包的时候,要手动解除对闭包的引用。例如:

function count() {
    let i = 0;
    function fn() {
        i++;
        console.log(`函数被调用了${i}次`);
    }
    return fn;
}

const fun = count();
fun(); // 输出: 函数被调用了1次
fun(); // 输出: 函数被调用了2次

// 不再需要 fun 函数时,手动解除引用
fun = null; 
// 此时,闭包和它所引用的变量就可以被垃圾回收机制回收

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>

说明:

JS初学者经常花很多时间才能习惯变量提升,还经常出现一些意想不到的bug,正因为如此,ES6 引入了块级作用域, 用let 或者 const声明变量,让代码写法更加规范和人性化。

二、函数进阶

函数提升

函数参数

箭头函数

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.函数参数

⑴. 动态参数

arguments 是函数内部内置的伪数组变量,它包含了调用函数时传入的所有实参

<!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() {
      // arguments 动态参数 只存在于 函数里面
      // 是伪数组 里面存储的是传递过来的实参
      console.log(arguments)
      let sum = 0
      for (let i = 0; i < arguments.length; i++) {
        sum += arguments[i]
      }
      console.log(sum)
    }
    getSum(2, 3, 4)
    getSum(1, 2, 3, 4, 2, 2, 3, 4)
  </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>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>

⑶.展开运算符

<!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 arr1 = [1, 2, 3]
    // 展开运算符 可以展开数组
    console.log(...arr1)

    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)

  </script>
</body>

</html>

⑷.展开运算符 or 剩余参数

3.箭头函数(重要)

⑴.基本语法

语法1:基本写法

语法2:只有一个参数可以省略小括号

语法3:如果函数体只有一行代码,可以写到一行上,并且无需写 return 直接返回值

语法4:加括号的函数体返回对象字面量表达式

<!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 fn1 = () => {
      console.log(123)
    }
    fn1()
    const fn2 = (x) => {
      console.log(x)
    }
    fn2(1)
    // 2. 只有一个形参的时候,可以省略小括号
    const fn3 = x => {
      console.log(x)
    }
    fn3(1)
    // // 3. 只有一行代码的时候,我们可以省略大括号
    const fn4 = x => console.log(x)
    fn4(1)
    //4. 只有一行代码的时候,可以省略return
    const fn5 = x => x + x
    console.log(fn5(1))
    // 5. 箭头函数可以直接返回一个对象
    const fn6 = (uname) => ({ uname: uname })
    console.log(fn6('刘德华'))

  </script>
</body>

</html>

总结:

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>
    // 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>

⑶. 箭头函数 this

①普通函数

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 以前this的指向:  谁调用的这个函数,this 就指向谁
        console.log(this)  // window
        // // 普通函数
        function fn() {
            console.log(this)  // window
        }
        window.fn()
        // 对象方法里面的this
        const obj = {
            name: 'andy',
            sayHi: function () {
                console.log(this)  // obj
            }
        }
        obj.sayHi()
    </script>

</body>

</html>

②箭头函数

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 2. 箭头函数的this  是上一层作用域的this 指向
        const fn = () => {
            console.log(this)  // window
        }
        fn()
        // 对象方法箭头函数 this
        const obj = {
            uname: '老师',
            sayHi: () => {
                console.log(this)  // this 指向谁? window
            }
        }
        obj.sayHi()
    </script>

</body>

</html>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const obj = {
            uname: 'pink老师',
            sayHi: function () {
                console.log(this)  // obj
                let i = 10
                const count = () => {
                    console.log(this)  // obj 
                }
                count()
            }
        }
        obj.sayHi()
    </script>

</body>

</html>

三、解构赋值

• 数组解构

• 对象解构 

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 arr = [100, 60, 80]
    // 数组解构 赋值
    // // const [max, min, avg] = arr
    const [max, min, avg] = [100, 60, 80]
    // // const max = arr[0]
    // // const min = arr[1]
    // // const avg = arr[2]
    console.log(max) // 100
    console.log(avg) // 80
    // 交换2个变量的值
    let a = 1
    let b = 2;
    [b, a] = [a, b]
    console.log(a, b)
  </script>
</body>

</html>

注意: js 前面必须加分号情况

<!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. 立即执行函数要加
    // (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)
  </script>
</body>

</html>

⑴.练习:独立完成数组解构赋值

⑵. 变量多 单元值少的情况:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 1. 变量多, 单元值少 , undefined
        const [a, b, c, d] = [1, 2, 3]
        console.log(a) // 1
        console.log(b) // 2
        console.log(c) // 3
        console.log(d) // undefined
    </script>

</body>

</html>

⑶.变量少 单元值多的情况:

⑷.利用剩余参数解决变量少 单元值多的情况:

⑸. 防止有undefined传递单元值的情况,可以设置默认值:

⑹. 按需导入,忽略某些返回值:

⑺. 支持多维数组的结构:

2. 对象解构

对象解构是将对象属性和方法快速批量赋值给一系列变量的简洁语法

⑴. 基本语法:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 对象解构
    // const obj = {
    //   uname: 'pink老师',
    //   age: 18
    // }
    // obj.uname
    // obj.age 
    // const uname = 'red老师'
    // 解构的语法
    const { uname, age } = {age: 18, uname: '老师' }
    // 等价于 const uname =  obj.uname
    // 要求属性名和变量名必须一直才可以
    console.log(uname)
    console.log(age)
    </script>

</body>

</html>

⑵.给新的变量名赋值:

可以从一个对象中提取变量并同时修改新的变量名

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        // 1. 对象解构的变量名 可以重新改名  旧变量名: 新变量名
        const { uname: username, age } = { uname: 'pink老师', age: 18 }

        console.log(username)
        console.log(age)
    </script>

</body>

</html>

⑶数组对象解构

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const pig = [
            {
                uname: '佩奇',
                age: 6
            }
        ]
        const [{ uname, age }] = pig
        console.log(uname)
        console.log(age)
    </script>

</body>

</html>

⑷.独立完成对象解构赋值

⑸. 多级对象解构:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const pig = {
            name: '佩奇',
            family: {
                mother: '猪妈妈',
                father: '猪爸爸',
                sister: '乔治'
            },
            age: 6
        }
        // // 多级对象解构
        const { name, family: { mother, father, sister } } = pig
        console.log(name)
        console.log(mother)
        console.log(father)
        console.log(sister)
    </script>

</body>

</html>

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <script>
        const person = [
            {
                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)
    </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>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 方法(重点)

注意:

1. forEach 主要是遍历数组

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>
    // 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>

五、渲染商品列表案例

<!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>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .list {
      width: 990px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
      padding-top: 100px;
    }

    .item {
      width: 240px;
      margin-left: 10px;
      padding: 20px 30px;
      transition: all .5s;
      margin-bottom: 20px;
    }

    .item:nth-child(4n) {
      margin-left: 0;
    }

    .item:hover {
      box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
      transform: translate3d(0, -4px, 0);
      cursor: pointer;
    }

    .item img {
      width: 100%;
    }

    .item .name {
      font-size: 18px;
      margin-bottom: 10px;
      color: #666;
    }

    .item .price {
      font-size: 22px;
      color: firebrick;
    }

    .item .price::before {
      content: "¥";
      font-size: 14px;
    }
  </style>
</head>

<body>
  <div class="list">
    <!-- <div class="item">
      <img src="" alt="">
      <p class="name"></p>
      <p class="price"></p>
    </div> -->
  </div>
  <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',
      },
    ]

    // 1. 声明一个字符串变量
    let str = ''
    // 2. 遍历数据 
    goodsList.forEach(item => {
      // console.log(item)  // 可以得到每一个数组元素  对象 {id: '4001172'}
      // const {id} =  item  对象解构
      const { name, price, picture } = item
      str += `
      <div class="item">
        <img src=${picture} alt="">
        <p class="name">${name}</p>
        <p class="price">${price}</p>
      </div>
      `
    })
    // 3.生成的 字符串 添加给 list 
    document.querySelector('.list').innerHTML = str
  </script>
</body>

</html>

六、筛选数组 filter 方法(重点)

<!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 arr = [10, 20, 30]
    // const newArr = arr.filter(function (item, index) {
    //   // console.log(item)
    //   // console.log(index)
    //   return item >= 20
    // })
    // 返回的符合条件的新数组

    const newArr = arr.filter(item => item >= 20)
    console.log(newArr)
  </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>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    .list {
      width: 990px;
      margin: 0 auto;
      display: flex;
      flex-wrap: wrap;
    }

    .item {
      width: 240px;
      margin-left: 10px;
      padding: 20px 30px;
      transition: all .5s;
      margin-bottom: 20px;
    }

    .item:nth-child(4n) {
      margin-left: 0;
    }

    .item:hover {
      box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.2);
      transform: translate3d(0, -4px, 0);
      cursor: pointer;
    }

    .item img {
      width: 100%;
    }

    .item .name {
      font-size: 18px;
      margin-bottom: 10px;
      color: #666;
    }

    .item .price {
      font-size: 22px;
      color: firebrick;
    }

    .item .price::before {
      content: "¥";
      font-size: 14px;
    }

    .filter {
      display: flex;
      width: 990px;
      margin: 0 auto;
      padding: 50px 30px;
    }

    .filter a {
      padding: 10px 20px;
      background: #f5f5f5;
      color: #666;
      text-decoration: none;
      margin-right: 20px;
    }

    .filter a:active,
    .filter a:focus {
      background: #05943c;
      color: #fff;
    }
  </style>
</head>

<body>
  <div class="filter">
    <a data-index="1" href="javascript:;">0-100元</a>
    <a data-index="2" href="javascript:;">100-300元</a>
    <a data-index="3" href="javascript:;">300元以上</a>
    <a href="javascript:;">全部区间</a>
  </div>
  <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: '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>
</body>

</html>

相关文章:

  • 弹珠堆放————java
  • 数据分析面试--京东
  • DRV8323芯片电机驱动芯片常见硬件连接线路的简介
  • Android开发layer-list
  • 【三十七周】文献阅读:通过具有长期融合池化的双流卷积网络进行的第一人称动作识别
  • 器件功耗模型原理
  • 全星研发项目管理APQP软件系统:汽车零部件制造行业的高效研发利器
  • Mysql配套测试之更新篇
  • ArcPy批量将栅格文件的属性表导出为Excel表格的方法
  • 【C++ 进阶】语句:从基础到实践
  • BMS电池管理系统
  • C语言-装饰器模式详解与实践 - LED控制系统
  • 菜单(路由)权限按钮权限路由进度条
  • Sqoop 常用命令
  • stm32标准库开发需要的基本文件结构
  • CUDA 学习(4)——CUDA 编程模型
  • 线段树与扫描线 —— 详解算法思想及其C++实现
  • Normal distribution (正态分布)
  • Windows安装Jenkins配置Allure踩坑,必须单独配置当前windows系统为新的node节点,才可在工具位置中指定节点服务器allure的位置
  • C语言-访问者模式详解与实践
  • 河南发布高温橙警:郑州、洛阳等地最高气温将达40℃以上
  • 复旦一校友捐赠1亿元,却不留名
  • 国际博物馆日|在辽宁省博物馆遇见敦煌
  • AG600“鲲龙”批生产首架机完成生产试飞
  • 蒲慕明院士:未来数十年不是AI取代人,而是会用AI的人取代不会用的
  • 马上评|重病老人取款身亡,如何避免类似悲剧?