ES6 | (二)ES6 新特性(下) | 尚硅谷Web前端ES6教程
文章目录
- 📚迭代器
- 🐇定义
- 🐇工作原理
- 🐇自定义遍历数据
- 📚生成器函数
- 🐇声明和调用
- 🐇生成器函数的参数传递
- 🐇生成器函数案例
- 📚Promise
- 📚Set
- 🐇Set的定义与使用
- 🐇集合实践
- 📚Map
- 📚class类
- 📚数值扩展
- 📚对象方法扩展
- 📚ES6模块化
- 🐇模块导出数据语法
- 🐇模块导入数据语法
学习链接:尚硅谷Web前端ES6教程
📚迭代器
🐇定义
- 遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署 Iterator 接口,就可以完成遍历操作。
- ES6 创造了一种新的遍历命令
for...of
循环,Iterator 接口主要供for...of
使用。 - 原生具备 iterator 接口的数据(可用for of 遍历):
Array
、Arguments
、Set
、Map
、String
、TypedArray
、NodeList
。<!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
方法返回一个包含value
和done
属性的对象。 - 应用场景:需要自定义遍历数据的时候,要想到迭代器。
🐇自定义遍历数据
<!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 构造函数:
-
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();
- ES6 中直接使用 extends 语法糖(更简洁高级的实现方式)来实现继承,同时可以重写父类的方法,直接在子类中重新写一次要重写的方法即可覆盖父类方法。
- 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__
、setPrototypeOf
、setPrototypeOf
可以直接设置对象的原型。
📚ES6模块化
- 模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。
- 模块化的好处
- 防止命名冲突
- 代码复用
- 高维护性
- ES6模块化语法 :模块功能主要由两个命令构成:
export
和import
。- 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";
相关文章:

ES6 | (二)ES6 新特性(下) | 尚硅谷Web前端ES6教程
文章目录 📚迭代器🐇定义🐇工作原理🐇自定义遍历数据 📚生成器函数🐇声明和调用🐇生成器函数的参数传递🐇生成器函数案例 📚Promise📚Set🐇Set的定…...

客户案例|用友NC财务系统上云
本文分享一次成功将用友NC财务系统上云的经验,主要涉及阿里云上Oracle ASM存储扩容,阿里云ESC RAC服务器扩容,阿里云上Oracle RAC数据库迁移等相关技术,一起来看看吧! 1 客户数据库上云背景 本次项目我司主要负责客户…...

OceanPen Art AI绘画系统内容讲解
在一个崇高的目标支持下,不停地工作,即使慢,也一定会获得成功。 —— 爱因斯坦 演示站点: ai.oceanpen.art官方论坛: www.jingyuai.com 💡技术栈 前端:VUE3后端:Java数据…...
类 Unix 系统的文件目录结构
以下是类 Unix 系统的文件目录结构、各个目录主要存放的文件以及缩写的全称的详细说明: 根目录 /: 全称: Root Directory说明:根目录是整个文件系统的起点,包含了所有其他目录和文件。 /bin 目录: 全称: Binary说明&a…...

外部存储器接口(EMIF)
外部存储器接口(EMIF) 该设备支持双核架构;为了为每个CPU子系统提供一个专用的EMIF,该设备支持两个EMIF模块——EMIF1和EMIF2。两个模块完全相同,具有相同的功能集,但具有不同的地址/数据大小。EMIF1在CPU…...
华为认证HCIP报名条件有哪些?考试要求介绍
华为HCIP认证是很多网络工程师的考证首选,尤其对于刚入行不久的网络工程师们来说,这个证书无论是从难度出发还是从含金量出发,都是值得一考的。 那么如果想报名华为HCIP认证有哪些条件以及考试要求,华为HCIP的报名需不需要通过机…...

【Python】变量的引用
🚩 WRITE IN FRONT 🚩 🔎 介绍:"謓泽"正在路上朝着"攻城狮"方向"前进四" 🔎🏅 荣誉:2021|2022年度博客之星物联网与嵌入式开发TOP5|TOP4、2021|2222年获评…...

nextjs13如何进行服务端渲染?
目录 一、创建一个新项目 二、动态获取后端数据进行服务端渲染出现的问题 三、nextjs13如何进行服务端渲染 nextjs13是nextjs的一个重大升级,一些原本在next12当中使用的API在nextjs13上使用十分不便。本文将着重介绍在nextjs13及以上版本当中进行服务端渲染的方…...

Redis-基础篇
Redis是一个开源、高性能、内存键值存储数据库,由 Salvatore Sanfilippo(网名antirez)创建,并在BSD许可下发布。它不仅可以用作缓存系统来加速数据访问,还可以作为持久化的主数据存储系统或消息中间件使用。Redis因其数…...

【好书推荐-第七期】《RTC程序设计:实时音视频权威指南》(音视频开发必看!)
😎 作者介绍:我是程序员洲洲,一个热爱写作的非著名程序员。CSDN全栈优质领域创作者、华为云博客社区云享专家、阿里云博客社区专家博主、前后端开发、人工智能研究生。公粽号:洲与AI。 🎈 本文专栏:本文收录…...

还在犹豫学不学?鸿蒙技术是否有前途的最强信号来了
2024年3月3日 上午10 点,深圳官方账号发布了一篇关于鸿蒙技术发展的重要文章,看到这篇文章后我非常激动,忍不住和大家分享一下! 华为鸿蒙系统自提出以来,网友们的态度各不相同,有嘲笑“安卓套壳”的&#x…...
webpack的plugin 插件教程
Webpack 是一个流行的前端打包工具,通过使用插件(plugin),我们可以对 Webpack 进行扩展和定制,实现更多功能和优化构建过程。在本教程中,我将向你介绍如何编写一个简单的 Webpack 插件,并演示如…...
v72.关于指针操作的补充
1.指针作为函数参数 调用函数时,传递参数的形式决定了是否可以修改这些参数。 传值方式:传递了参数给函数,并且这个参数是基本数据类型,如(int,float),那么函数内对参数的任何操作…...

【学习心得】爬虫JS逆向通解思路
我希望能总结一个涵盖大部分爬虫逆向问题的固定思路,在这个思路框架下可以很高效的进行逆向爬虫开发。目前我仍在总结中,下面的通解思路尚不完善,还望各位读者见谅。 一、第一步:明确反爬手段 反爬手段可以分为几个大类 &#…...

如何使用Logstash搜集日志传输到es集群并使用kibana检测
引言:上一期我们进行了对Elasticsearch和kibana的部署,今天我们来解决如何使用Logstash搜集日志传输到es集群并使用kibana检测 目录 Logstash部署 1.安装配置Logstash (1)安装 (2)测试文件 ÿ…...

AutoEncoder和 Denoising AutoEncoder学习笔记
参考: 【1】 https://lilianweng.github.io/posts/2018-08-12-vae/ 写在前面: 只是直觉上的认识,并没有数学推导。后面会写一篇(抄)大一统文章(概率角度理解为什么AE要选择MSE Loss) TOC 1 Au…...

计算机系统基础
一、计算机系统概述 计算机系统:硬件软件,软件包括系统软件和应用软件 二、计算机组成结构 三、存储结构 3.1 层次化存储结构 3.2 Cache Cache(高速缓存)的功能:提高CPU数据输入输出的速率,突破冯.若依曼瓶…...

live555学习 - 环境准备
环境:Ubuntu 16.04.7 ffmpeg-6.1 1 代码下载 最新版本: http://www.live555.com/liveMedia/public/ 历史版本下载 https://download.videolan.org/pub/contrib/live555/ 选择版本live.2023.01.19.tar.gz ps:没有选择新版本是新版本在…...

C++ 模拟OJ
目录 1、1576. 替换所有的问号 2、 495. 提莫攻击 3、6. Z 字形变换 4、38. 外观数列 5、 1419. 数青蛙 1、1576. 替换所有的问号 思路:分情况讨论 ?zs:左边没有元素,则仅需保证替换元素与右侧不相等;z?s:左右都…...

MariaDB MaxScale实现mysql8读写分离
MaxScale 是干什么的? MaxScale是maridb开发的一个mysql数据中间件,其配置简单,能够实现读写分离,并且可以根据主从状态实现写库的自动切换,对多个从服务器能实现负载均衡。 MaxScale 实验环境 中间件192.168.142.13…...
云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?
大家好,欢迎来到《云原生核心技术》系列的第七篇! 在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能
下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能,包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...

零基础设计模式——行为型模式 - 责任链模式
第四部分:行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习!行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想:使多个对象都有机会处…...

ArcGIS Pro制作水平横向图例+多级标注
今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作:ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等(ArcGIS出图图例8大技巧),那这次我们看看ArcGIS Pro如何更加快捷的操作。…...
ip子接口配置及删除
配置永久生效的子接口,2个IP 都可以登录你这一台服务器。重启不失效。 永久的 [应用] vi /etc/sysconfig/network-scripts/ifcfg-eth0修改文件内内容 TYPE"Ethernet" BOOTPROTO"none" NAME"eth0" DEVICE"eth0" ONBOOT&q…...
力扣-35.搜索插入位置
题目描述 给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...