• ES6 | (二)ES6 新特性(下) | 尚硅谷Web前端ES6教程


    学习链接:尚硅谷Web前端ES6教程

    在这里插入图片描述

    📚迭代器

    🐇定义

    • 遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
    • ES6 创造了一种新的遍历命令 for...of 循环,Iterator 接口主要供for...of使用。
    • 原生具备 iterator 接口的数据(可用for of 遍历):ArrayArgumentsSetMapStringTypedArrayNodeList
      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>迭代器title>
      head>
      <body>
          <script>
              //使用next()方法遍历原生自带iterator接口的数据
              // 遍历 Map
              const mp = new Map();
              mp.set('a', 1);
              mp.set('b', 2);
              mp.set('c', 3);
              let iter1 = mp[Symbol.iterator]();
              console.log(iter1.next()); 
              console.log(iter1.next()); 
              console.log(iter1.next()); 
              console.log(iter1.next()); 
              // 遍历数组
              let xiyou = ['唐僧','孙悟空','猪八戒','沙僧'];
              let iter2 = xiyou[Symbol.iterator]();
              console.log(iter2.next()); 
              console.log(iter2.next()); 
              console.log(iter2.next()); 
              console.log(iter2.next()); 
      
              //实际上直接使用 for...of 方法遍历即可
              const mp2 = new Map();
              mp2.set('a', 1);
              mp2.set('b', 2);
              mp2.set('c', 3);
              for (let [k, v] of mp) {
                  console.log(k, v);
              }
          script>
      body>
      html>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      在这里插入图片描述
      在这里插入图片描述

    🐇工作原理

    • 创建一个指针对象,指向当前数据结构的起始位置。
    • 第一次调用对象的next方法,指针自动指向数据结构的第一个成员。
    • 接下来不断调用`next方法,指针一直往后移动,直到指向最后一个成员。
    • 每调用next方法返回一个包含valuedone属性的对象。
    • 应用场景:需要自定义遍历数据的时候,要想到迭代器。

    🐇自定义遍历数据

    DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>自定义遍历数据title>
    head>
    
    <body>
        <script>
            // 需求:遍历对象中的数组
            const youyi = {
                uname: '右一',
                course: [ '可视化', '信息检索', '大数据安全', '类脑' ],
                // 通过自定义 [Symbol.iterator]() 方法
                [Symbol.iterator]() {
                    // 初始指针对象指向数组第一个
                    let index = 0;
                    // 保存 youyi 的 this 值
                    let _this = this;
                    return {
                        next: function () {
                            // 不断调用 next 方法,直到指向最后一个成员
                            if (index < _this.course.length) {
                                return { value: _this.course[index++], done: false };
                            } else {
                                // 每调用next 方法返回一个包含value 和done 属性的对象
                                return { value: undefined, done: true };
                            }
                        }
                    }
                }
            }
            // for...of直接遍历达到目的
            for (let v of youyi) {
                console.log(v);
            }
        script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    在这里插入图片描述

    📚生成器函数

    🐇声明和调用

    • 生成器函数是 ES6 提供的一种 异步编程解决方案,语法行为与传统函数完全不同。
    • *的位置没有限制
      • 使用function * gen()yield可以声明一个生成器函数。生成器函数返回的结果是迭代器对象,调用迭代器对象的next方法可以得到yield语句后的值。
      • 每一个yield相当于函数的暂停标记,也可以认为是一个分隔符,每调用一次next(),生成器函数就往下执行一段。
      • next方法可以传递实参,作为yield语句的返回值。
      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>生成器title>
      head>
      <body>
          <script>    
              //生成器其实就是一个特殊的函数
              //函数代码的分隔符
              function * gen(){
                  console.log(111);
                  yield '一只没有耳朵';
                  console.log(222);
                  yield '一只没有尾部';
                  console.log(333);
                  yield '真奇怪';
                  console.log(444);
              }
      
              let iterator = gen();
              console.log(iterator.next());
              console.log(iterator.next());
              console.log(iterator.next());
              console.log(iterator.next());
      
              // 遍历
              for(let v of gen()){
                  console.log(v);
              }
          script>
      body>
      html>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34

    在这里插入图片描述
    在这里插入图片描述

    🐇生成器函数的参数传递

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>生成器函数参数title>
    head>
    <body>
        <script>
            function* generator(arg) {
                console.log(arg); // 生成器第 1 段
                let one = yield 111;
                console.log(one); // 生成器第 2 段
                let two = yield 222;
                console.log(two); // 生成器第 3 段
                let three = yield 333; 
                console.log(three); // 生成器第 4 段
            }
    
            let iter = generator('aaa'); // 传给生成器第 1 段
            console.log(iter.next());
            console.log(iter.next('bbb')); // 传给生成器第 2 段,作为这一段开始的 yield 语句返回值
            console.log(iter.next('ccc')); // 传给生成器第 3 段,作为这一段开始的 yield 语句返回值
            console.log(iter.next('ddd')); // 传给生成器第 4 段,作为这一段开始的 yield 语句返回值
        script>
    body>
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    在这里插入图片描述

    🐇生成器函数案例

    • 需求:1s 后控制台输出 111 2s后输出 222 3s后输出 333。
    • 传统方式:嵌套太多,代码复杂
      setTimeout(() => {
      	console.log(111);
      	setTimeout(() => {
      		console.log(222);
      		setTimeout(() => {
      			console.log(333);
      		}, 3000);
      	}, 2000);
      }, 1000);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • 生成器实现:结构简洁明了
      DOCTYPE html>
      <html lang="en">
      
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>生成器函数实例title>
      head>
      
      <body>
          <script>
              function one(){
                  setTimeout(()=>{
                      console.log(111);
                      iterator.next();
                  },1000)
              }
      
              function two(){
                  setTimeout(()=>{
                      console.log(222);
                      iterator.next();
                  },2000)
              }
      
              function three(){
                  setTimeout(()=>{
                      console.log(333);
                      iterator.next();
                  },3000)
              }
      
              function * gen(){
                  yield one();
                  yield two();
                  yield three();
              }
      
              //调用生成器函数
              let iterator = gen();
              iterator.next();
          script>
      body>
      
      html>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45

    📚Promise

    以下简单过一下 Promise,更多还要进一步深入学习,后续补充

    • Promise的定义和使用

      • Promise 是 ES6 引入的异步编程的新解决方案。
      • 语法上 Promise 是一个构造函数,用来封装异步操作并可以获取其成功或失败的结果
      • 一个 Promise 必然处于以下几种状态之一
        • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
        • 已兑现(fulfilled):意味着操作成功完成。
        • 已拒绝(rejected):意味着操作失败。
      • Promise 的使用
        • Promise 构造函数:new Promise((resolve, reject)=>{})
        • Promise.prototype.then方法:该方法用于指定当前Promise对象状态改变时的回调函数。它接收两个参数,第一个参数是状态改变为Fulfilled时的回调函数,第二个参数(可选)是状态改变为Rejected时的回调函数。当Promise对象的状态已经是Fulfilled时调用then方法,回调函数会立即执行。
        • Promise.prototype.catch方法:该方法用于指定当前Promise对象状态变为Rejected时的回调函数。它和then方法的用法类似,但只接收一个参数,即状态变为Rejected时的回调函数。如果Promise对象的状态已经是Rejected,再调用catch方法时,回调函数会立即执行。catch方法返回一个新的Promise对象,可以链式调用后续的then方法。
        DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Promise基本语法title>
        head>
        <body>
            <script>
                //实例化 Promise 对象
                const p = new Promise(function(resolve, reject){
                    // 使用 setTimeout 模拟请求数据库数据操作
                    setTimeout(function(){
                        // 这个异步请求数据库数据操作是否正确返回数据
                        let isRight = true;
                        if (isRight) {
                            let data = '数据库中的数据';
                            // 设置 Promise 对象的状态为操作成功
                            resolve(data);
                        } else {
                            let err = '数据读取失败!'
                            // 设置 Promise 对象的状态为操作失败
                            reject(err);
                        }
                    }, 1000);
                });
        
                //调用 promise 对象的 then 方法
                p.then(function(value){
                    console.log(value);
                }, function(reason){
                    console.error(reason);
                })
            script>
        body>
        html>
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
    • Promise封装读取文件

      //1. 引入 fs 模块
      const fs = require('fs');
      
      //2. 调用方法读取文件
      // fs.readFile('./resources/为学.md', (err, data)=>{
      //     //如果失败, 则抛出错误
      //     if(err) throw err;
      //     //如果没有出错, 则输出内容
      //     console.log(data.toString());
      // });
      
      //3. 使用 Promise 封装
      const p = new Promise(function(resolve, reject){
          fs.readFile("./resources/为学.md", (err, data)=>{
              //判断如果失败
              if(err) reject(err);
              //如果成功
              resolve(data);
          });
      });
      
      p.then(function(value){
          console.log(value.toString());
      }, function(reason){
          console.log("读取失败!!");
      });
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26

      在这里插入图片描述

    📚Set

    🐇Set的定义与使用

    • ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of』进行遍历。
    • 定义一个 Set 集合:
      let st1 = new Set();
      let st2 = new Set([可迭代对象]);
      
      • 1
      • 2
    • 集合(这里假设有一个集合 st)的属性和方法:
      • st.size:返回集合个数
      • st.add(item):往集合中添加一个新元素 item,返回当前集合
      • st.delete(item):删除集合中的元素,返回 boolean 值
      • st.has(item):检测集合中是否包含某个元素,返回 boolean 值
      • st.clear():清空集合
      • 集合转为数组:[...st]
      • 合并两个集合:[...st1, ...st2]
      DOCTYPE html>
      <html lang="en">
      <head>
          <meta charset="UTF-8">
          <meta name="viewport" content="width=device-width, initial-scale=1.0">
          <title>集合title>
      head>
      <body>
          <script>
              //声明一个 set
              let s = new Set();
              let s2 = new Set(['大事儿','小事儿','好事儿','坏事儿','小事儿']);
      
              //元素个数
              console.log(s2.size);
              //添加新的元素
              s2.add('喜事儿');
              //删除元素
              s2.delete('坏事儿');
              //检测
              console.log(s2.has('糟心事'));
              for(let v of s2){
                  console.log(v);
              }
              //清空
              s2.clear();
              console.log(s2);
          script>
      body>
      html>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30

    在这里插入图片描述

    🐇集合实践

    DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Set 实践title>
    head>
    <body>
        <script>
            let arr = [1,2,3,4,5,4,3,2,1];
            //1. 数组去重
            let result = [...new Set(arr)];
            console.log(result);
            //2. 交集
            let arr2 = [4,5,6,5,6];
            let result2 = [...new Set(arr)].filter(item => new Set(arr2).has(item));
            console.log(result2);
    
            //3. 并集
            let union = [...new Set([...arr, ...arr2])];
            console.log(union);
    
            //4. 差集
            let diff = [...new Set(arr)].filter(item => !(new Set(arr2).has(item)));
            console.log(diff);
        script>
    body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    在这里插入图片描述

    📚Map

    • ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合。但是 “键” 的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of』进行遍历。
    • 定义一个map
      let mp1 = new Map();
      mp1.set('aaa', 111);
      mp1.set('bbb', 222);
      mp1.set('ccc', 333);
      
      let mp2 = new Map([
          ['aaa', 111],
          ['bbb', 222],
          ['ccc', 333]
      ]);
      
      console.log(mp1['aaa']); // 111
      console.log(mp2.get('bbb')); // 222
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
    • Map 的属性和方法:(k 为键,v为值)
      • size:返回 Map 的元素(键值对)个数。
      • set(k, v):增加一个键值对,返回当前 Map。
      • get(k):返回键值对的键值。
      • has():检测 Map 中是否包含某个元素。
      • clear():清空集合,返回 undefined。

    📚class类

    • ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class 关键字,可以定义类。基本上,ES6 的 class 可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的 class 写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已。
    • function构造函数的继承
      //手机
      function Phone(brand, price){
          this.brand = brand;
          this.price = price;
      }
      
      Phone.prototype.call = function(){
          console.log("我可以打电话");
      }
      
      //智能手机
      function SmartPhone(brand, price, color, size){
          Phone.call(this, brand, price);
          this.color = color;
          this.size = size;
      }
      
      //设置子级构造函数的原型
      SmartPhone.prototype = new Phone;
      // 矫正 constructor 指向
      SmartPhone.prototype.constructor = SmartPhone;
      
      //声明子类的方法
      SmartPhone.prototype.photo = function(){
          console.log("我可以拍照")
      }
      
      SmartPhone.prototype.playGame = function(){
          console.log("我可以玩游戏");
      }
      
      const chuizi = new SmartPhone('锤子',2499,'黑色','5.5inch');
      
      console.log(chuizi);
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
      • 30
      • 31
      • 32
      • 33
      • 34
    • extends类继承和方法的重写
      • ES6 中直接使用 extends 语法糖(更简洁高级的实现方式)来实现继承,同时可以重写父类的方法,直接在子类中重新写一次要重写的方法即可覆盖父类方法。
        class Phone{
          //构造方法
           constructor(brand, price){
               this.brand = brand;
               this.price = price;
           }
           //父类的成员属性
           call(){
               console.log("我可以打电话!!");
           }
        }
        
        class SmartPhone extends Phone {
           //构造方法
           constructor(brand, price, color, size){
               super(brand, price);// Phone.call(this, brand, price)
               this.color = color;
               this.size = size;
           }
        
           photo(){
               console.log("拍照");
           }
        
           playGame(){
               console.log("玩游戏");
           }
        
           call(){
               console.log('我可以进行视频通话');
           }
        }
        
        const xiaomi = new SmartPhone('小米',799,'黑色','4.7inch');
        console.log(xiaomi);
        xiaomi.call();
        xiaomi.photo();
        xiaomi.playGame();
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
        • 18
        • 19
        • 20
        • 21
        • 22
        • 23
        • 24
        • 25
        • 26
        • 27
        • 28
        • 29
        • 30
        • 31
        • 32
        • 33
        • 34
        • 35
        • 36
        • 37
        • 38
      在这里插入图片描述
    • getter和setter🔥
      • 当属性拥有 get/set 特性时,属性就是访问器属性。代表着在访问属性或者写入属性值时,对返回值做附加的操作。而这个操作就是 getter/setter 函数。
      • 使用场景: getter 是一种语法,这种 get 将对象属性绑定到 查询该属性时将被调用的函数。适用于某个需要动态计算的成员属性值的获取。setter 则是在修改某一属性时所给出的相关提示。
        // get 和 set  
        class Phone{
            get price(){
                console.log("价格属性被读取了");
                return 'iloveyou';
            }
        
            set price(newVal){
                console.log('价格属性被修改了');
            }
        }
        
        //实例化对象
        let s = new Phone();
        
        console.log(s.price);
        s.price = 'free';
        
        • 1
        • 2
        • 3
        • 4
        • 5
        • 6
        • 7
        • 8
        • 9
        • 10
        • 11
        • 12
        • 13
        • 14
        • 15
        • 16
        • 17
      在这里插入图片描述

    📚数值扩展

    • Number.EPSILON是 JavaScript 表示的最小精度,一般用来处理浮点数运算。例如可以用于两个浮点数的比较。
      let equal = (x, y) => Math.abs(x - y) < Number.EPSILON;
      console.log(0.1 + 0.2 === 0.3); // false
      console.log(equal(0.1 + 0.2, 0.3)); // true
      
      • 1
      • 2
      • 3
    • Number.isFinite检测一个数值是否为有限数。
      console.log(Number.isFinite(100)); // false
      console.log(Number.isFinite(100 / 0)); // true
      console.log(Number.isFinite(Infinity)); // false
      
      • 1
      • 2
      • 3
    • ES6 给 Number 添加了 parseInt 方法,Number.parseInt 完全等同于 parseInt,将字符串转为整数,或者进行进制转换。Number.parseFloat 则等同于 parseFloat()。
    • Number.isInteger() 判断一个数是否为整数。
    • Math.trunc() 将数字的小数部分抹掉。
    • Math.sign 判断一个数到底为正数 负数 还是零

    📚对象方法扩展

    • Object.is比较两个值是否严格相等,与『===』行为基本一致。
    • Object.assign对象的合并,将源对象的所有可枚举属性,复制到目标对象。
    • __proto__setPrototypeOfsetPrototypeOf可以直接设置对象的原型。

    📚ES6模块化

    • 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
    • 模块化的好处
      • 防止命名冲突
      • 代码复用
      • 高维护性
    • ES6模块化语法 :模块功能主要由两个命令构成:exportimport
      • export命令用于规定模块的对外接口。
      • import命令用于输入其他模块提供的功能。

    🐇模块导出数据语法

    • 单个导出
      // 单个导出
      export let uname = 'Rick';
      export let sayHello = function () {
          console.log('Hi, bro!');
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
    • 合并导出
      let uname = 'Rick';
      let sayHello = function () {
          console.log('Hi, bro!');
      }
      // 合并导出
      export { uname, sayHello };
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 默认导出
      // 默认导出
      export default {
          uname: 'Rick',
          sayHello: function () {
              console.log('Hi, bro!');
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

    🐇模块导入数据语法

    • 通用导入
      import * as m1 from './js/m1.js';
      import * as m2 from './js/m2.js';
      import * as m3 from './js/m3.js';
      
      • 1
      • 2
      • 3
    • 解构赋值导入
      import { uname, sayHello } from './js/m1.js';
      // 有重复名可以设置别名
      import { uname as uname2, sayHello as sayHello2 } from './js/m2.js';
      console.log(uname);
      // 配合默认导出
      import {default as m3} from "./src/js/m3.js";
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
    • 简便方式导入,针对默认暴露
      import m3 from "./src/js/m3.js";
      
      • 1
  • 相关阅读:
    高阶 DS --- AVL 树
    xpath常用语法
    IC岗位详解| 一位合格的模拟版图工程师需要具备哪些能力?
    【RAZ】kids 电脑版本
    设计模式之工厂模式
    亚马逊云科技与德勤中国推出新工具,有效缓解生成式AI时代下的安全问题
    怎么彻底粉碎文件夹?文件还能恢复吗?操作过程在这里
    大厂面试题-JVM中的三色标记法是什么?
    【毕业设计】深度学习手势检测识别系统 - 卷积神经网络 opencv python
    WeakHashMap 和 HashMap 的区别是什么,何时使用?
  • 原文地址:https://blog.csdn.net/m0_63398413/article/details/136238337