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

文章目录

  • 📚迭代器
    • 🐇定义
    • 🐇工作原理
    • 🐇自定义遍历数据
  • 📚生成器函数
    • 🐇声明和调用
    • 🐇生成器函数的参数传递
    • 🐇生成器函数案例
  • 📚Promise
  • 📚Set
    • 🐇Set的定义与使用
    • 🐇集合实践
  • 📚Map
  • 📚class类
  • 📚数值扩展
  • 📚对象方法扩展
  • 📚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接口的数据// 遍历 Mapconst 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>
    
    在这里插入图片描述
    在这里插入图片描述

🐇工作原理

  • 创建一个指针对象,指向当前数据结构的起始位置。
  • 第一次调用对象的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>

在这里插入图片描述

📚生成器函数

🐇声明和调用

  • 生成器函数是 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>
    

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

🐇生成器函数的参数传递

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

在这里插入图片描述

🐇生成器函数案例

  • 需求:1s 后控制台输出 111 2s后输出 222 3s后输出 333。
  • 传统方式:嵌套太多,代码复杂
    setTimeout(() => {console.log(111);setTimeout(() => {console.log(222);setTimeout(() => {console.log(333);}, 3000);}, 2000);
    }, 1000);
    
  • 生成器实现:结构简洁明了
    <!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>
    

📚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>
      
  • 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("读取失败!!");
    });
    

    在这里插入图片描述

📚Set

🐇Set的定义与使用

  • ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了 iterator 接口,所以可以使用『扩展运算符』和『for…of』进行遍历。
  • 定义一个 Set 集合:
    let st1 = new Set();
    let st2 = new Set([可迭代对象]);
    
  • 集合(这里假设有一个集合 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>//声明一个 setlet 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>
    

在这里插入图片描述

🐇集合实践

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

在这里插入图片描述

📚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
    
  • 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);
    
  • 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();
      
    在这里插入图片描述
  • 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';
      
    在这里插入图片描述

📚数值扩展

  • 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
    
  • Number.isFinite检测一个数值是否为有限数。
    console.log(Number.isFinite(100)); // false
    console.log(Number.isFinite(100 / 0)); // true
    console.log(Number.isFinite(Infinity)); // false
    
  • 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!');
    }
    
  • 合并导出
    let uname = 'Rick';
    let sayHello = function () {console.log('Hi, bro!');
    }
    // 合并导出
    export { uname, sayHello };
    
  • 默认导出
    // 默认导出
    export default {uname: 'Rick',sayHello: function () {console.log('Hi, bro!');}
    }
    

🐇模块导入数据语法

  • 通用导入
    import * as m1 from './js/m1.js';
    import * as m2 from './js/m2.js';
    import * as m3 from './js/m3.js';
    
  • 解构赋值导入
    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";
    
  • 简便方式导入,针对默认暴露
    import m3 from "./src/js/m3.js";
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/268116.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SpringBoot3-核心原理

1. 事件和监听器 1. 生命周期监听 场景&#xff1a;监听应用的生命周期 1. 监听器-SpringApplicationRunListener 自定义SpringApplicationRunListener来监听事件&#xff1b; 编写SpringApplicationRunListener 实现类在 META-INF/spring.factories 中配置 org.springfram…

解决鸿蒙模拟器卡顿的问题

缘起 最近在学习鸿蒙的时候&#xff0c;发现模拟器非常卡&#xff0c;不要说体验到鸿蒙的丝滑&#xff0c;甚至到严重影响使用的程度。 根据我开发Android的经验和在论坛翻了一圈&#xff0c;最终总结出了以下几个方案。 创建模拟器 1、在DevEco Virtual Device Configurat…

Revit-二开之立面视图创建FilledRegion-(3)

在上一篇博客中介绍了FilledRegion的创建方法,这种方法通常只在平面视图中适用,在三维视图中也是无法创建的(目前研究的是这样的,如果有其他方法,请赐教)。 本片文章介绍一个下在立面视图中创建FilledRegion的方法,主要操作是在立面视图中拾取一个点,然后以该点为原点,…

(3)(3.1) FlightDeck FrSky发射器应用程序

文章目录 前言 1 概述 2 Turnkey Packages 3 参数说明 前言 ​Craft and Theory 的 FlightDeck 可让你轻松查看飞行模式、高度、速度、姿态和关键系统警报&#xff0c;包括故障保护和电池错误&#xff0c;如电池不平衡警告和发射机低电量警报。 1 概述 Craft and Theory 的…

如何通过python写接口自动化脚本对一个需要调用第三方支付的报名流程进行测试?

对于需要调用第三方支付的报名流程进行接口自动化测试&#xff0c;可以通过以下步骤来编写Python代码&#xff1a; 1. 确认API需求 首先&#xff0c;需要确认报名流程的API需求和预期功能。这涉及到对业务需求的理解和API设计的分析。 2. 安装依赖库 在Python程序中&#x…

Linux——进程控制

目录 进程创建 fork函数 fork用法 fork失败原因 进程终止 进程常见退出方法 进程等待 进程等待的必要性 wait() waitpid() status 进程替换 替换函数 execl execv execlp execvp execle execvpe execve系统调用 命名的理解 简易shell 进程创建 fork函数…

[计算机网络]--I/O多路转接之poll和epoll

前言 作者&#xff1a;小蜗牛向前冲 名言&#xff1a;我可以接受失败&#xff0c;但我不能接受放弃 如果觉的博主的文章还不错的话&#xff0c;还请点赞&#xff0c;收藏&#xff0c;关注&#x1f440;支持博主。如果发现有问题的地方欢迎❀大家在评论区指正 目录 一、poll函…

通过修改host文件来访问GitHub

前言&#xff1a; 由于国内环境的原因&#xff0c;导致我们无法流畅的访问GitHub&#xff0c;。 但是我们可以采取修改host文件来实现流畅访问。 缺点&#xff1a;需要不定时的刷新修改。 操作流程 一、查询IP地址 以下地址可以查询ip地址 http://ip.tool.chinaz.com/ htt…

VisualStudio2022安装教程

1.下载安装 最近要帮机器视觉的同学介绍C#&#xff0c;所以把安装过程梳理一下给大家&#xff1a; VisualStudio 是微软公司的强大的集成开发环境&#xff0c;这里不多说&#xff0c;感兴趣可以上网搜下 学习的话&#xff0c;下载免费的社区版就好 下载地址&#xff1a;https:…

k8s二进制部署的搭建

1.1 常见k8s安装部署方式 ●Minikube Minikube是一个工具&#xff0c;可以在本地快速运行一个单节点微型K8S&#xff0c;仅用于学习、预览K8S的一些特性使用。 部署地址&#xff1a;Install Tools | Kubernetes ●Kubeadm Kubeadm也是一个工具&#xff0c;提供kubeadm init…

【JS】解构赋值注意点,解构赋值报错

报错代码 const 小明 { email: 6, pwd: 66 } const 小刚 { email: 9, pwd: 99 }const { email } 小明 const { email } 小刚 报错图 原因 2个常量重复&#xff0c;重复在同一个作用域内是不能重复的&#xff0c;例如大括号内{const a 1; const a 2} 小伙伴A提问 问&…

2023年第十四届蓝桥杯大赛软件类省赛C/C++大学A组真题

2023年第十四届蓝桥杯大赛软件类省赛C/C大学A组部分真题和题解分享 文章目录 蓝桥杯2023年第十四届省赛真题-平方差思路题解 蓝桥杯2023年第十四届省赛真题-更小的数思路题解 蓝桥杯2023年第十四届省赛真题-颜色平衡树思路题解 蓝桥杯2023年第十四届省赛真题-买瓜思路题解 蓝桥…

springcloud和基础服务的搭建以及封装

代码仓库地址&#xff1a;https://github.com/zhaoyiwen-wuxian/springcloud-common page分页也进行了封装&#xff0c;只需要添加到pom中&#xff0c;将会自动进行分页&#xff0c;并且后端不需要写任何的分页数据。只需要前端自己传分页参数即可&#xff0c;并且里面封装了很…

Neoverse S3 系统 IP:机密计算和多芯片基础设施 SoC 的基础

第三代Neoverse系统IP Neoverse S3 产品推出了我们的第三代基础设施特定系统 IP&#xff0c;这是下一代基础设施 SOC 的理想基础&#xff0c;适用于从 HPC 和机器学习到 Edge 和 DPU 的各种应用。S3 机箱专注于为我们的合作伙伴提供 Chiplet、机密计算等关键创新以及 UCIe、DD…

2024.03.01作业

1. 基于UDP的TFTP文件传输 #include "test.h"#define SER_IP "192.168.1.104" #define SER_PORT 69 #define IP "192.168.191.128" #define PORT 9999enum mode {TFTP_READ 1,TFTP_WRITE 2,TFTP_DATA 3,TFTP_ACK 4,TFTP_ERR 5 };void get_…

每日一题——LeetCode1572.矩阵对角线元素的和

方法一 遍历矩阵 如果矩阵中某个位置&#xff08;x,y&#xff09;处于对角线上&#xff0c;那么这个位置必定满足&#xff1a; xy 或 xy len-1 &#xff08;len为矩阵长度&#xff09; var diagonalSum function(mat) {let len mat.length;let sum 0;for (let i 0; i …

智慧运维是什么,智能建筑设施运维管理系统怎么样

推进数字化转型。数字化转型是中小企业向专业化、信息化发展的必由之路。通过引进先进的信息技术和管理系统&#xff0c;公司应加大对数字技术的投入&#xff0c;提高生产流程、成本和效率&#xff0c;提高企业的竞争力。 操作界面的简单易用性 综合页面设计简单明了&#xff…

构建安全的REST API:OAuth2和JWT实践

引言 大家好&#xff0c;我是小黑&#xff0c;小黑在这里跟咱们聊聊&#xff0c;为什么REST API这么重要&#xff0c;同时&#xff0c;为何OAuth2和JWT在构建安全的REST API中扮演着不可或缺的角色。 想象一下&#xff0c;咱们每天都在使用的社交媒体、在线购物、银行服务等等…

Stable Diffusion 模型分享:AAM XL (Anime Mix)(动漫截屏风格 XL)

本文收录于《AI绘画从入门到精通》专栏&#xff0c;专栏总目录&#xff1a;点这里。 文章目录 模型介绍生成案例案例一案例二案例三案例四案例五案例六案例七案例八 下载地址 模型介绍 AAM XL (Anime Mix) 是一个动漫截屏风格的模型&#xff0c;是 AAM - AnyLoRA Anime Mix 模…

手撕Java集合之简易版Deque(LinkedList)

在目前&#xff0c;许多互联网公司的面试已经要求能手撕集合源码&#xff0c;集合源码本身算是源码里比较简单的一部分&#xff0c;但是要在面试极短的10来分钟内快速写出一个简易版的源码还是比较麻烦的&#xff0c;很容易出现各种小问题。所以在平时就要注重这方面的联系。 以…