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

ES6 特性全面解析与应用实践

1、let

let 关键字用来声明变量,使用let 声明的变量有几个特点:

1) 不允许重复声明

2) 块儿级作用域

3) 不存在变量提升

4) 不影响作用域链

5) 暂时性死区

6)不与顶级对象挂钩

在代码块内,使用let命令声明变量之前,该变量都是不可用的。这在语法上,称为“暂时性死区”。该变量在声明之前使用都属于“暂时性死区“。

应用场景:以后声明变量使用let 就对了

  <script>//声明变量格式let a;let b, c, d;let e = 100;let f = 521,g = "iloveyou",h = [];//1. 变量不能重复声明,防止变量被污染// let star = '王老师';// let star = '余老师';  //会报错//2. 块儿级作用域  避免暴露成全程作用域,影响别人{let girl = '王老师';var boy='张老师'}console.log(girl);//报错console.log(boy);//张老师// if  else  while  for  这些语句里,都是有块级作用域的//for 循环的计算器,就很合适let命令for(let i=0;i<3;i++){console.log(i);//0,1,2}console.log(i);//报错//3. 不影响作用域链//作用域链:内层作用域 ——> 外层作用域 ——> 全局作用域{let school = "bdqn";function fn() {console.log(school);//在fn作用域没有,还是会向上寻找}fn();}//4. 不存在变量提升// console.log(song);// let song = '恋爱达人';// 5、let暂时性死区var a = 1;if (true) {a = 2; // 报错,初始化前不能访问a,也就是在同一个作用域中,不可以访问,再定义let a = 1;}// 6、 不与顶层对象挂钩var myname='zhangsan'let myage=18console.log(window.myname);//zhangsanconsole.log(window.myage);//undefined</script>

2、const

const 关键字用来声明常量,const 声明有以下特点

1) 声明必须赋初始值

2) 标识符一般为大写(建议)

3) 不允许重复声明

4) 值不允许修改

const实际上保存的,并不是变量的值不得改动,而是变量指向的那个内存地址所保存的数据不得改动。对于简单类型的数据(数值、字符串、布尔值),值就保存在变量指向的那个内存地址,因此等同于常量。

但对于复合类型的数据(主要是对象和数组),变量指向的内存地址,保存的只是一个指向实际数据的指针,const只能保证这个指针是固定的(即总是指向另一个固定的地址),至于它指向的数据结构是不是可变的,就完全不能控制了。

注意: 对象属性修改和数组元素变化不会出发const 错误, 对象地址不可改变。

5) 块儿级作用域

6)、 不与顶层对象挂钩

应用场景:声明对象类型使用const,非对象类型声明选择let

 <script>//声明常量const SCHOOL = 'bdqn';//注意事项//1. 一定要赋初始值// const A;//2. 一般常量使用大写(潜规则)// const a = 100;//3. 常量的值不能修改// SCHOOL = 'bdqn';//4. 块儿级作用域// {//     const PLAYER = 'UZI';// }// console.log(PLAYER);//5. 对于数组和对象的元素修改, 不算做对常量的修改, 不会报错const TEAM = ['UZI','MXLG','Ming','Letme'];// TEAM.push('Meiko');// 6、 不与顶层对象挂钩var myname = "zhangsan";const myage = 18;console.log(window.myname); //zhangsanconsole.log(window.myage); //undefined</script>

面试题1.let和const的区别(/var,let,const的区别?)

let声明的变量可以改变,值和类型都可以改变(let:声明的是变量);

const声明的常量不可以改变,这意味着,const一旦声明,就必须立即初始化,不能以后再赋值,当然数组和对象等复合类型的变量,变量名不指向数据,而是指向数据所在的地址。

const只保证变量名指向的地址不变,并不保证该地址的数据不变。

letconst总结

let 声明的变量会产生块作用域,var 不会产生块作用域

const 声明的常量也会产生块作用域

不同代码块之间的变量无法互相访问

注意: 对象属性修改和数组元素变化不会出发 const 错误 (数组和对象存的是引用地址)

应用场景:声明对象类型使用 const,非对象类型声明选择 let

cosnt声明必须赋初始值,标识符一般为大写,值不允许修改。

3、变量的解构赋值

ES6 允许按照一定模式,从数组和对象中快速的提取成员,对变量进行赋值,这被称为解构赋值。

本质上,只要等号两边的模式相同,左边的变量就会被赋予对应的值。

1>解构分类

(1)、数组的解构

ES6中允许从数组中提取值,按照对应位置,对变量赋值

<script>//数组的解构const F4 = ['小沈阳','刘能','赵四','宋小宝'];let [xiao, liu, zhao, song] = F4;console.log(xiao);console.log(liu);console.log(zhao);console.log(song); // 省略变量let [a, , c] = [1, 2, 3]; console.log(a, c);//1,3
</script>
(2)、对象的解构

对象的解构与数组有一个重要的不同。数组的元素是按顺序排列的,变量的取值由它的位置决定;而对象的属性没有次序,变量必须与属性同名,才能取到正确的值,否则解构失败就是undefined。


<script>//对象的解构const zhao = {name: "赵本山",age: "不详",xiaopin: function () {console.log("我可以演小品");},data: {list: ["贾玲", "沈腾", "···"],},};let {name:n,//起别名age=18,//可以定义默认值xiaopin,data: { list },//可以解构下一级数据} = zhao;console.log(n);//赵本山console.log(age);console.log(xiaopin);console.log(list);xiaopin();let {xiaopin} = zhao;xiaopin();</script>
(3)、字符串解构
let [a, b, c] = "hello";console.log(a); //hconsole.log(b); //econsole.log(c); //llet { length } = "hello";console.log(length);//5

2、解构应用

(1)、变量值交换
let a = 1;
let b = 2;
[a, b] = [b, a];
console.log(a);
(2)、函数返回多个值
 function myfun() {return [2, 3, 4];}let [a, b, c] = myfun();console.log([a, b, c]);//[2, 3, 4]console.log(a);//2console.log(b);//3console.log(c);//4
(3)、函数参数传参数
 function myfun([a, b, c]) {console.log(a);}myfun([4, 5, 6]);

4、模板字符串

ES6 引入新的声明字符串的方式 『``』 '' ""

  <script>//1. 声明// let str = `我是一个字符串哦!`;// console.log(str, typeof str);//2. 内容中可以直接出现换行符let str = `<ul><li>孙悟空</li><li>猪八戒</li><li>沙悟净</li><li>白骨精</li></ul>`;//3. 变量拼接 ${lovest}let lovest = '沈腾';let out = `${lovest}是我心目中最搞笑的演员!!`;console.log(out);</script>

5、字符串扩展

(1)、 includes函数

判断字符串中是否存在指定字符,返回布尔值, 语法:string.includes("xxx")

<script>let myname = "hello";console.log(myname.includes("e")); //trueconsole.log(myname.startsWith("o")); //falseconsole.log(myname.endsWith("k")); //false</script>	

(2)、repeat函数

repeat()方法返回一个新字符串,表示将原字符串重复n次。str.repeat(数值)

  <script>let res = "hello";console.log(res.repeat(1)); //helloconsole.log(res.repeat(0)); //""console.log(res.repeat(2.5)); //hellohelloconsole.log(res.repeat("2"); //hellohello</script>

6、数值扩展

(1)、Number.EPSILON

JavaScript 表示的最小精度,一般用在浮点数运算上,

EPSILON 属性的值接近于 2.2204460492503130808472633361816E-16

console.log(0.1 + 0.2 === 0.3);//falsefunction equal(a, b) {if (Math.abs(a - b) < Number.EPSILON) {return true;} else {return false;}}console.log(equal(0.1 + 0.2, 0.3));//true

(2)二进制和八进制

   let b = 0b1010;// 0b开头 二进制let o = 0o77;// 0o开头 八进制let d = 100; //十进制let x = 0xff;//0x开头 十六进制

(3)、 Number.isFinite

如果传递的值是有限数字,则返回true。 布尔值,字符串,对象,数组等所有其他内容均返回false:

console.log(Number.isFinite(100));//true
console.log(Number.isFinite(100/0));//false
console.log(Number.isFinite(Infinity));//false
console.log(Number.isFinite(NaN));  //false

(4)、 Number.isNaN

检测一个数值是否为 NaN,只有对于NaN才返回true,非NaN一律返回false。

console.log(Number.isNaN(123));//false

(5)、Number.parseInt Number.parseFloat

字符串转整数,必须以数字开头

console.log(Number.parseInt('5211314love'));console.log(Number.parseFloat('3.1415926神奇'));

(6)、 Number.isInteger

判断一个数是否为整数

 console.log(Number.isInteger(5));//trueconsole.log(Number.isInteger(2.5));//false

(7)、Math.trunc

将数字的小数部分抹掉

console.log(Math.trunc(3.5));//3

(8)、Math.sign

判断一个数到底为正数负数还是零,对于非数值,会先将其转换为数值。

console.log(Math.sign(100));//1
console.log(Math.sign(0));//0
console.log(Math.sign(-20000));//-1	

7、数组扩展

(1)、Array.from()方法

将伪数组或可遍历对象转换为真正的数组。

  <script>//   举例1:Array.from("12345"); // [1,2,3,4,5]//   举例2:let arr1 = {1: "a",2: "b",length: 3,};console.log(Array.from(arr1)); // [undefined, 'a', 'b']//举例3function test() {console.log(Array.from(arguments));// [1, 2, 3]}test(1, 2, 3);//举例4:选择器let divs = document.querySelectorAll("div");console.log(Array.from(divs));//[div, div, div]</script>

(2)、array.find() 方法

该方法主要应用于查找第一个符合条件的数组元素

它的参数是一个回调函数。

在回调函数中可以写你要查找元素的条件,当条件成立为true时,返回该元素。

如果没有符合条件的元素,返回值为undefined

<script>//   举例1:let arr1 = [1, 2, 3, 2];let res = arr1.find((item) => {//   console.log(item,'item');//return item>2return  item == 2});console.log(res); //2, 如果未找到,返回undefined//   举例2:let person = [{ name: "张三", age: 16 },{ name: "李四", age: 17 },{ name: "王五", age: 18 },];let target = person.find((item, index) => {return  item.name == "张三";});console.log(target.name);//张三</script>

(3)、array.findindex()方法

定义:用于找出第一个符合条件的数组成员的位置,如果没有找到返回-1。

  <script>let ary = [1,5, 10, 15];let index = ary.findIndex((item, index) => {return item > 9;});console.log(index); // 2   第一个比9大的数字在索引值为2的部位</script>

(4)、array.includes()方法

定义:判断某个数组是否包含给定的值,返回布尔值。

<script>let ary = [1, 5, 10, 15];console.log(ary.includes(5)); //true</script>

(5)、Array.of()方法

将一组值转化为数组,即新建数组

 <script>let arr1 = new Array(3);console.log(arr1); // [,,]let arr2 = Array.of(3);console.log(arr2); // [3]</script>

(6)、fill方法

使用自己想要的参数替换原数组内容,但是会改变原来的数组

可以传多个参数

1个参数:默认从数组第一位开始替换

2个参数:(替换的值,替换索引位置)

3个参数:(替换的值,替换索引开始位置,替换索引结束位置【不包括】)

 <script>let arr1 = new Array(3).fill("hello");let arr2 = ["猪八戒", "孙悟空", "唐僧"].fill("kerwin", 1, 2);console.log(arr1); // ['hello', 'hello', 'hello']console.log(arr2); //  ['猪八戒', 'kerwin', '唐僧']</script>

(7)、最新数组方法

JavaScript中31个数组方法,包括es5,es6新增方法(关注收藏,持续更新)_js数组方法以及es6新增的数组方法有哪些-CSDN博客

(8)、spread 扩展运算符

扩展运算符(spread)也是三个点(...)。它好比rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

  <script>// 『...』 扩展运算符能将『数组』转换为逗号分隔的『参数序列』//声明一个数组 ...const tfboys = ['易烊千玺','王源','王俊凯'];// => '易烊千玺','王源','王俊凯'// 声明一个函数function chunwan(){console.log(arguments);}chunwan(...tfboys);// chunwan('易烊千玺','王源','王俊凯')</script>

扩展运算符的应用

<body><div></div><div></div><div></div><script>//1. 数组的合并 const kuaizi = ['王太利','肖央'];const fenghuang = ['曾毅','玲花'];// 数组的合并 第一种方式// const zuixuanxiaopingguo = kuaizi.concat(fenghuang);// 数组的合并 第二种方式const zuixuanxiaopingguo = [...kuaizi, ...fenghuang];console.log(zuixuanxiaopingguo);//2. 数组的克隆(深拷贝)const sanzhihua = ['E','G','M'];const sanyecao = [...sanzhihua];//  ['E','G','M']console.log(sanyecao);//3. 将伪数组转为真正的数组const divs = document.querySelectorAll('div');const divArr = [...divs];console.log(divArr);// arguments    </script>
</body>

8、对象拓展

ES6 新增了一些 Object 对象的方法

(1)、简写对象

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

 <script>//ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。//这样的书写更加简洁let name = 'bdqn';let change = function(){console.log('我们可以改变你!!');}const school = {// name:name,//属性名和变量值一样,可以简写一个name,change, //外部定义的函数fun: function () {console.log("我是复杂写法");},improve() {//直接在对象里定义函数console.log("我是简写");},};console.log(school);</script>

注意:对象简写形式简化了代码,所以以后用简写就对了

(2)、 Object.is

比较两个值是否严格相等,与『===』行为基本一致 (+0 与 NaN)

console.log(Object.is(120, 120));// === 
console.log(Object.is(NaN, NaN));// true
console.log(NaN === NaN);// false

(3) 、Object.assign

对象的合并,将原对象的所有可枚举属性,复制到目标对象,后面的对象会覆盖前面的对象一样的属性

Object.assign(target, object1,object2)的第一个参数是目标对象,后面可以跟一个或多个源对象作为参数。

target:参数合并后存放的对象

object1:参数1

object2:参数2

const obj1 = {name: "tom",age: 18,};const obj2 = {name: "bob",age: 28,sex: "男",};console.log(Object.assign(obj1, obj2));//{name: 'bob', age: 28, sex: '男'}

(4) 、setPrototypeOf、 getPrototypeOf

可以直接设置对象的原型,不建议使用

setPrototypeOf(school, cities)

参数1:给谁设置原型对象 school

参数2:设置哪个原型对象 cities

const school = {name: "bdqn",};const cities = {xiaoqu: ["北京", "上海", "深圳"],};// 设置原型Object.setPrototypeOf(school, cities);// 获取原型Object.getPrototypeOf(school);console.log(school);

9、函数扩展

1>、箭头函数

ES6 允许使用「箭头」(=>)定义函数。

箭头函数只能简写函数表达式,不能简写声明式函数

 function fn() {} // 不能简写const fun = function () {}; // 可以简写
const obj = {
fn: function () {}, // 可以简写
};
(1)、 语法:() =>{}

():函数的形参

=>:必须的语法,指向代码块

{}:代码块

   <script> // ES6 允许使用「箭头」(=>)定义函数。//声明一个函数/* let fn = function(){} *//*  let fn = (a,b) => {return a + b;} *///调用函数// let result = fn(1, 2);// console.log(result);</script> 
(2)、箭头函数的特性

this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值,没有自己的this

不能作为构造实例化对象 会报错

不能使用 arguments 变量

箭头函数的简写

1) 省略小括号, 当形参有且只有一个的时候

2) 函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的

执行结果

 <script>    //箭头函数的特性//1. this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值,没有自己的thisfunction getName() {console.log(this.name);}let getName2 = () => {console.log(this.name);};//设置 window 对象的 name 属性window.name = "北大青鸟";const school = {name: "bdqn",};//直接调用,this指向window// getName();// getName2();//call 方法调用// getName.call(school);  //指向school// getName2.call(school);  //指向window//2. 不能作为构造实例化对象  会报错/*    let Person = (name, age) => {this.name = name;this.age = age;}let me = new Person('xiao',30);console.log(me); *///3. 不能使用 arguments 变量/*    let fn = () => {console.log(arguments);}fn(1,2,3); *///4. 箭头函数的简写//1) 省略小括号, 当形参有且只有一个的时候/*   let add = n => {return n + n;}console.log(add(9)); *///2) 省略花括号, 当代码体只有一条语句的时候, 此时 return 必须省略// 而且语句的执行结果就是函数的返回值/*  let pow = (n) => n * n;console.log(pow(8)); */</script>

注意:箭头函数不会更改this 指向,用来指定回调函数会非常合适

补充this指向问题汇总

1、作为普通函数被调用时--this指向全局对象window
window.age = 18;function fn() {console.log(this.age);//18}fn()
2、对象方法里的this

当函数作为对象方法被调用时this指向该对象

 var obj = {age: 18,fn: function () {console.log(this === obj);//trueconsole.log(this.age);//18}}console.log(obj.fn());
3、构造函数里面的this

构造函数里的this指向 new创建的实例化对象(没有return的情况下)

如果构造函数内出现了return并且是一个object对象那么最终的运算结果返回这个对象

只要构造函数不返回数据或者返回基本数据类型 this仍然指向实例

  function Fn() {this.age = 18;//此时a.age是return的结果20return {age: 20,};}let a = new Fn();console.log(a.age); //20
4、call&& apply&&bind

在function的原型上有三个方法 call apply bind,所有函数都是Function的实例,所以所有的函数都可以调用这三个方法,而这三个方法都是用来改变this指向的

定义:call(thisObj,Object) 调用一个对象的一个方法,以另一个对象替换当前对象。

说明:call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

function fn(x, y) {console.log('加油');console.log(this);//this指向windowconsole.log(x + y);
}
var o = {name: 'andy'
}
fn.call()//call 呼叫 可以调用函数
fn.call(o, 1, 2)//第一个值是this指向, 后边实参
fn.apply(o, [10, 20])//apply传递数组
fn.call(10, 20)//this-->new Numbe(10) x-->20 y-->undefined 
5、箭头函数中this

箭头函数里面没有自己的this 他只会从自己的作用域链上一层继承this

 this.age = 20;var obj = {age: 18,fn: () => {console.log(this.age);//20}}obj.fn()

2> 参数默认值

(1)、 形参初始值 具有默认值的参数, 一般位置要靠后(潜规则)

  function add(a, b, c = 10) {return a + b + c;}//let res1 = add(1, 2, 3);//6let res2 = add(1,1);//12cons
ole.log(res2);

(2)、 与解构赋值结合

  function connect({ name, age, sex, price = "3000" }) {console.log(name);console.log(age);console.log(sex);console.log(price);}connect({name: "章三",age: 20,sex: "男",// price: 4000,});

(3)、这个默认值的方式箭头函数也可以使用

const fn = (a = 10) => {console.log(a);};fn(); // 不传递参数的时候,函数内部的 a 就是 10fn(20); // 传递了参数 20 的时候,函数内部的 a 就是 20

注意: 箭头函数如果你需要使用默认值的话,那么一个参数的时候也需要写()

10、rest 参数

ES6 引入rest 参数,用于获取函数的实参,用来代替arguments

   <script>// ES5 获取实参的方式/*   function date(){console.log(arguments);}date('大白','二黑','三孩'); */// rest 参数/*  function date(...args) {console.log(args); // filter some every map}date("大白", "二黑", "三孩"); */// rest 参数必须要放到参数最后/*   function fn(a,b,...args){console.log(a);console.log(b);console.log(args);}fn(1,2,3,4,5,6); */</script>

注意:rest 参数非常适合不定个数参数函数的场景

11、Symbol

(1)、Symbol 基本使用

ES6 引入了一种新的原始数据类型Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。

undefined string symbol object null number boolean

Symbol 特点

1) Symbol 的值是唯一的,用来解决命名冲突的问题

2) Symbol 值不能与其他数据进行运算

3) Symbol 定义的对象属性不能使用for…in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名

注: 遇到唯一性的场景时要想到Symbol

script>//创建方式//创建Symbol方式1let s = Symbol();// console.log(s, typeof s);//创建方式2//  Symbol()函数可以接受一个字符串作为参数,//  表示对 Symbol 实例的描述。这主要是为了在控制台显示,比较容易区分。let s2 = Symbol('bdqn');//'bdqn'这个内容只是个标识let s3 = Symbol('bdqn');console.log('s2===s3',s2===s3);//false// 创建方式3  Symbol.for  // Symbol.for并不是每次都会创建一个新的symbol,它会先检索symbol表中是否有,没有再创建新的,有就返回上次存储的let s4 = Symbol.for('bdqn');let s5 = Symbol.for('bdqn');console.log('s4===s5',s4===s5);//true//注意事项//1:不能与其他数据进行运算//    let result = s + 100;//    let result = s > 100;//    let result = s + s;</script>

(2)、Symbol创建对象属性

可以给对象添加属性和方法

<script>//向对象中添加方法 up downlet game = {name: "俄罗斯方块",up: function () {},down: function () {},};//声明一个对象/* let methods = {up: Symbol(),down: Symbol(),};game[methods.up] = function () {console.log("我可以改变形状");};game[methods.down] = function () {console.log("我可以快速下降!!");};console.log(game); */let youxi = {name:"狼人杀",[Symbol('say')]: function(){console.log("我可以发言")},[Symbol('zibao')]: function(){console.log('我可以自爆');}}console.log(youxi);</script>

(3)、Symbol的内置对象

除了定义自己使用的Symbol 值以外,ES6 还提供了11 个内置的Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。

Symbol.hasInstance

当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法

Symbol.isConcatSpreadable

对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开。

Symbol.species

创建衍生对象时,会使用该属性

Symbol.match

当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值。

Symbol.replace

当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值。

Symbol.search

当该对象被str.search(myObject)方法调用时,会返回该方法的返回值。

Symbol.split

当该对象被str.split(myObject)方法调用时,会返回该方法的返回值。

Symbol.iterator

对象进行for...of循环时,会调用Symbol.iterator方法,返回该对象的默认遍历器

Symbol.toPrimitive

该对象被转为原始类型的值时,会调用这个方法,返回该对象对应的原始类型值。

Symbol.toStringTag

在该对象上面调用toString方法时,返回该方法的返回值

Symbol.unscopables

该对象指定了使用with关键字时,哪些属性会被with环境排除。

12、迭代器

遍历器(Iterator)就是一种机制。它是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署Iterator 接口,就可以完成遍历操作。(Iterator 接口就是对象里面的一个属性)

Iterator 接口就是对象的一个属性

Iterator 的作用有三个:

一是为各种数据结构,提供一个统一的、简便的访问接口;

二是使得数据结构的成员能够按某种次序排列;

三是 ES6 创造了一种新的遍历命令for...of循环,Iterator 接口主要供for...of循环

1) ES6 创造了一种新的遍历命令for...of 循环,Iterator 接口主要供for...of 消费

2) 原生具备iterator 接口的数据(可用for of 遍历)

a) Array

b) Arguments

c) Set

d) Map

e) String

f) TypedArray

g) NodeList

3) 工作原理(1)创建一个指针对象,指向当前数据结构的起始位置。也就是说,遍历器对象本质上,就是一个指针对象。

(2)第一次调用指针对象的next方法,可以将指针指向数据结构的第一个成员。

(3)第二次调用指针对象的next方法,指针就指向数据结构的第二个成员。

(4)不断调用指针对象的next方法,直到它指向数据结构的结束位置。

(5) 每调用next 方法返回一个包含value 和done 属性的对象

done:是否循环完毕

注: 迭代器就是按照一定的顺序对元素进行遍历的过程

   <script>//声明一个数组const xiyou = ["唐僧", "孙悟空", "猪八戒", "沙僧"];//使用 for...of 遍历数组   for (let v of xiyou) {console.log(v);}let iterator = xiyou[Symbol.iterator]();console.log(iterator);//调用对象的next方法console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());</script>

13、生成器

Generator 函数是 ES6 提供的一种异步编程解决方案,语法行为与传统函数完全不同

Generator 函数是一个状态机,封装了多个内部状态。

执行 Generator 函数会返回一个遍历器对象,也就是说,Generator 函数除了状态机,还是一个遍历器对象生成函数。返回的遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

(1)、生成器基本语法

通过function关键字后的星号(*)来表示,函数中会用到新的关键字yield。星号(*)可以紧挨着function关键字,也可以在中间添加一个空格

<script>//生成器其实就是一个特殊的函数//异步编程  纯回调函数  node fs  ajax mongodb//yield 函数代码的分隔符,分割代码function* cook() {let i = 1;console.log(`我被执行了${i}次`);yield "盛米";i++;console.log(`我被执行了${i}次`);yield "淘米";i++;console.log(`我被执行了${i}次`);yield "煮米";i++;console.log(`我被执行了${i}次`);}let iterator = cook(); //返回一个迭代器对象,里面有个next()方法//函数不会一下子执行完毕,会以yield为分割线,调一次next,执行一次console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());console.log(iterator.next());//遍历// for(let v of cook()){//     console.log(v);// }</script>

代码说明:

1) cook()前的星号 * 表明它是一个生成器

2) 生成器函数返回的结果是迭代器对象,调用迭代器对象的next 方法可以得到yield 语句后的值

3) yield 相当于函数的暂停标记,每当执行完一条yield语句后函数就会自动停止执行,也可以认为是函数的分隔符,每调用一次next方法,执行一段代码

4) next 方法可以传递实参,作为yield 语句的返回值

5)yield关键字只可在生成器内部使用,在其他地方使用会导致程序抛出错误

(2)、生成器函数参数

概念:next('BBB')传入的参数作为上一个next方法的返回值。

  <script>function * gen(arg) {console.log(arg);//AAAlet one = yield "aaa";console.log(one);//BBBlet two = yield "bbb";console.log(two);//CCClet three = yield "ccc";console.log(three);//DDD}//执行获取迭代器对象let iterator = gen("AAA ");console.log(iterator.next()); //{value: 'aaa', done: false}//next方法可以传入的实参,作为yield语句整体返回的结果console.log(iterator.next("BBB"));console.log(iterator.next("CCC"));console.log(iterator.next("DDD"));</script>
(3)、生成器函数实例

(3)、生成器函数实例

 <script>// 异步编程   文件操作 网络操作(ajax, request) 数据库操作// 需求:1s 后控制台输出 111  2s后输出 222  3s后输出 333// 回调地狱(一层套一层,不停回调)/* setTimeout(() => {console.log(111);setTimeout(() => {console.log(222);setTimeout(() => {console.log(333);}, 3000);}, 2000);}, 1000); */// 生成器函数解决回调地域//生成3个异步函数function one() {setTimeout(() => {console.log(111);iterator.next(); //函数one执行完毕后,调用next(),执行下一个异步函数}, 1000);}function two() {setTimeout(() => {console.log(222);iterator.next(); //函数two执行完毕后,调用next(),执行下一个异步函数}, 2000);}function three() {setTimeout(() => {console.log(333);iterator.next(); //函数three执行完毕后,调用next(),执行下一个异步函数}, 3000);}//用生成器函数将三个异步函数放在yield语句中function* gen() {yield one();yield two();yield three();}//调用生成器函数let iterator = gen();iterator.next(); //调用一次next执行一个yield语句,这个只会执行one()回调</script>

14、Promise

(0)、回调地狱

回调地狱:就是回调函数嵌套过多导致的

当一个回调函数嵌套一个回调函数的时候

就会出现一个嵌套结构

当嵌套的多了就会出现回调地狱的情况

比如我们发送三个 ajax 请求

第一个正常发送

第二个请求需要第一个请求的结果中的某一个值作为参数

第三个请求需要第二个请求的结果中的某一个值作为参数

 <script>function fn() {setTimeout(function () {console.log("111");setTimeout(function () {console.log("222");setTimeout(function () {console.log("333");}, 1000);}, 2000);}, 3000);}fn();</script>

(1)、什么是promise

Promise是ES6异步编程的一种解决方案(目前最先进的解决方案是async和await的搭配(ES8),但是它们是基于promise的)

从语法上讲,Promise是一个对象或者说是构造函数,用来封装异步操作并可以获取其成功或失败的结果。

(2)、Promise对象的状态:

a对象的状态不受外界影响。

Promise 对象通过自身的状态,来控制异步操作。Promise 实例具有三种状态。

pending: 等待中,或者进行中,表示还没有得到结果

resolved(Fulfilled): 已经完成,表示得到了我们想要的结果,可以继续往下执行

rejected: 也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行

bPromise对象三种状态不受外界影响,三种的状态的变化途径只有两种。

从“未完成”到“成功”

从“未完成”到“失败”

一旦状态发生变化,就凝固了,不会再有新的状态变化。这也是 Promise 这个名字的由来,它的英语意思是“承诺”,一旦承诺成效,就不得再改变了。这也意味着,Promise 实例的状态变化只可能发生一次。

c、Promise 的最终结果只有两种。

异步操作成功,Promise 实例传回一个值(value),状态变为fulfilled。

异步操作失败,Promise 实例抛出一个错误(error),状态变为rejected。

(3)、Promise语法格式

//写法一
new Promise(function (resolve, reject) {// resolve 表示成功的回调// reject 表示失败的回调
}).then(function (res) {// 成功的函数
}).catch(function (err) {// 失败的函数
})
//写法二
new Promise(function (resolve, reject) {// resolve 表示成功的回调// reject 表示失败的回调
}).then(function (res) {// 成功的函数
},function(res){// 失败的函数
})

出现了new关键字,就明白了Promise对象其实就是一个构造函数,是用来生成Promise实例的。能看出来构造函数接收了一个函数作为参数,该函数就是Promise构造函数的回调函数,该函数中有两个参数resolve和reject,这两个参数也分别是两个函数!

简单的去理解的话

resolve函数的目的是将Promise对象状态变成成功状态,在异步操作成功时调用,将异步操作的结果,作为参数传递出去。

reject函数的目的是将Promise对象的状态变成失败状态,在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

注意:then方法可以接受两个函数,第一个函数为promise状态为成功的回调函数,第二个函数为promise状态为失败的回调函数可以不写,一般用catch方法捕获promise状态为失败的异常信息)

(4)、代码示例

  const promise = new Promise((resolve,reject)=>{//异步代码setTimeout(()=>{// resolve(['111','222','333'])reject('error')},2000)})//写法一promise.then((res)=>{//兑现承诺,这个函数被执行console.log('success',res);}).catch((err)=>{//拒绝承诺,这个函数就会被执行console.log('fail',err);})//写法二promise.then(function (value) {console.log(value);},function (reason) {console.error(reason);});

(5)、Promise封装Ajax

<script>// 接口地址: https://api.apiopen.top/getJokeconst p = new Promise((resolve, reject) => {//1. 创建对象const xhr = new XMLHttpRequest();//2. 初始化xhr.open("GET", "https://api.apiopen.top/getJoke");//3. 发送xhr.send();//4. 绑定事件, 处理响应结果xhr.onreadystatechange = function () {//判断if (xhr.readyState === 4) {//判断响应状态码 200-299if (xhr.status >= 200 && xhr.status < 300) {//表示成功resolve(xhr.response);} else {//如果失败reject(xhr.status);}}};});//指定回调p.then(function (value) {console.log(value);},function (reason) {console.error(reason);});</script>

(6)、promise的对象方法

p1,p2,p3为promise的实例对象

Promise.then()方法

then方法的返回结果是 Promise 对象, 返回对象状态由回调函数的执行结果决定,结果有以下:

a. 如果回调函数中返回的结果是 非 promise 类型的属性, 状态为成功, 返回值为对象的成功的值

b. 是 promise 对象,内部返回的状态,就是它的状态

c. 抛出错误 返回失败的promise状态

链式调用 可以改变回调地狱的情况

 <script>//创建 promise 对象const p = new Promise((resolve, reject) => {setTimeout(() => {resolve("用户数据");// reject('出错啦');}, 1000);});const result = p.then((value) => {console.log(value);//1. 非 promise 类型的属性// return 'iloveyou';//2. 是 promise 对象// return new Promise((resolve, reject)=>{//     // resolve('ok');//     reject('error');// });//3. 抛出错误// throw new Error('出错啦!');throw "出错啦!";},(reason) => {console.warn(reason);});//链式调用p.then(value=>{}).then(value=>{}); </script>

Promise.catch()

一般用catch方法捕获promise状态为失败的异常信息

 <script>const p = new Promise((resolve, reject)=>{setTimeout(()=>{//设置 p 对象的状态为失败, 并设置失败的值reject("出错啦!");}, 1000)});// p.then(function(value){}, function(reason){//     console.error(reason);// });p.catch(function(reason){console.warn(reason);});</script>

Promise.all()

并发处理多个异步任务,所有任务都执行完成才能得到结果

Promise.all( [p1,p2,p3] ) .then ( (result) => {consoleog (result)
})

Promise.race()

只返回异步任务数组中第一个执行完的结果,其他任务仍在执行,不过结果会被抛弃

应用场景:

几个接口返回一样的数据,哪个快用哪个

Promise.race ( [p1,p2] ).then ( (result)=>{
console. log (result)
})

15、set

(1)、set基本知识

ES6 提供了新的数据结构 Set(集合)。它类似于数组,但成员的值都是唯一的,集合实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历

实例的属性和方法

size:返回Set实例的成员总数。

Set.prototype.add(value):添加某个value。

Set.prototype.delete(value):删除某个value,返回一个布尔值,表示删除是否成功。

Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。

Set.prototype.clear():清除所有成员,没有返回值。

 <script>//声明一个 setlet s = new Set();let s2 = new Set(['张三','李四','王五','赵六']);//元素个数// console.log(s2.size);//添加新的元素// s2.add('jack');//删除元素// s2.delete('李四');//检测// console.log(s2.has('王五'));//清空// s2.clear();// console.log(s2);//遍历元素for(let v of s2){console.log(v);}</script>

set遍历

Set.prototype.keys():返回键名的遍历器

Set.prototype.values():返回键值的遍历器

Set.prototype.entries():返回键值对的遍历器

Set.prototype.forEach():遍历每个成员

let arr = new Set(["red", "green", "blue"]);// 返回键名for (let item of arr.keys()) {// console.log(item);//red green blue}// 返回键值for (let item of arr.values()) {// console.log(item);//red green blue}// set 键名=键值// 返回键值对for (let item of arr.entries()) {// console.log(item);// ['red', 'red']   ['green', 'green'] ['blue', 'blue']}// set也有forEach()方法arr.forEach((value, key) => console.log(key + " : " + value));

(2)、set实践

  <script>let arr = [1, 2, 3, 4, 5, 4, 3, 2, 1];//1. 数组去重//   let result = new Set(arr);//   result = [...result];//   console.log(result);//2. 交集let arr2 = [4, 5, 6, 5, 6];/* 可以先去重,避免做无用对比 *///   let result = [...new Set(arr)].filter(item => {//       let s2 = new Set(arr2);//数组2去重后的结果  4 5 6//       if(s2.has(item)){//           return true;//       }else{//           return false;//       }//   });//简化版本// let result = [...new Set(arr)].filter((item) => new Set(arr2).has(item));//console.log(result);//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>

16、Map

ES6 提供了Map 数据结构。它类似于对象,也是键值对的集合。但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。Map 也实现了iterator 接口,所以可以使用『扩展运算符』和『for…of…』进行遍历。

Map 的属性和方法:

1) size 返回Map 的元素个数

2) set 增加一个新元素,返回当前Map

3) get 返回键名对象的键值

4) has 检测Map 中是否包含某个元素,返回boolean 值

5) clear 清空集合,返回undefined

<script>/* map升级后的对象,键名可以是对象 *///声明 Maplet m = new Map();//添加元素 set()m.set('name','bdqn');//键名:字符串m.set('change', function(){//键名:字符串console.log("我们可以改变你!!");});let key = {school : '北京大学'};m.set(key, ['北京','上海','深圳']);//键名:对象//size// console.log(m.size);//删除// m.delete('name');//获取  get()// console.log(m.get('change'));// console.log(m.get(key));//清空  clear()// m.clear();//遍历// for(let v of m){//     console.log(v);// }console.log(m);</script>

17、class类

JavaScript 语言中,生成实例对象的传统方法是通过构造函数,ES6 提供了更接近传统语言的写法,引入了 Class(类)这个概念,作为对象的模板。通过class关键字,可以定义类。

1> class初体验

 <script>// //es5通过构造函数实现// function PersonO(username, password) {//   this.username = username;//   this.password = password;// }// // 添加方法// PersonO.prototype.getstr = function () {//   console.log("用户名:" + this.username + ",密码:" + this.password);// };// // 实例化对象// const po1 = new PersonO("章三", "abc123");// console.log(po1);// po1.getstr();// es6实现  class方法实现class PersonN {//构造方法  constructor名字不能修改// 当我们new实例对象的时候,这个方法自动执行constructor(username, password) {this.username = username;this.password = password;}//方法必须使用该语法, 不能使用 ES5 的对象完整形式getstr() {console.log("用户名:" + this.username + ",密码:" + this.password);}//ES5 的对象完整形式  报错// getstr:function () {}}const pn1 = new PersonN("123456", "789012");pn1.getstr();</script>

说明:使用class关键词 声明类,constructor为构造方法,一个类必须有constructor()方法,如果没有显式定义,一个空的constructor()方法会被默认添加,

this关键字则代表实例对象,

getstr()为普通方法,不要用es5完整写法,getstr()存在 prototype上。

pn1.constructor === pn1.prototype.constructor // true

2> 类的静态成员

es5可以直接给构造函数添加属性,方法,这些属性方法不在这个构造函数实例的对象身上

对应的es6中,类相当于实例的原型,所有在类中定义的方法,都会被实例继承。如果在一个方法前,加上static关键字,就表示该方法不会被实例继承,而是直接通过类来调用,这就称为“静态方法”。

 <script>// es5function Phone() {}// 给Phone添加静态属性Phone.name = "手机";Phone.call = function () {console.log("我可以打电话");};//实例化对象let apple = new Phone();// console.log(apple.name); //undefined//apple.change(); //报错  实例身上是没有构造函数身上的属性和方法// Phone.call(); //我可以打电话class PhoneN{static  name='手机'static  game(){console.log('我可以打游戏');}}let  p1=new PhoneN()console.log(p1.name);//undefinedconsole.log(PhoneN.name);//手机</script>

3> 类的继承

(1)、es5的继承
<script>//手机   父级构造函数function Phone(brand, price) {this.brand = brand;this.price = price;}Phone.prototype.call = function () {console.log("我可以打电话");};//智能手机   子级构造函数function SmartPhone(brand, price, color, size) {//通过call方法改变this指向,指向SmartPhone的实例对象Phone.call(this, brand, price);//子类独有的属性this.color = color;this.size = size;}//设置子级构造函数的原型   让SmartPhone的实例对象有父类的属性方法SmartPhone.prototype = new Phone();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);</script>
(2)、es6的继承
 <script>// 定义父类class Student {//构造方法constructor(realname, age) {this.realname = realname;this.age = age;}//父类的成员属性play(str) {console.log("我会玩" + str);}}//定义子类class ItStudent extends Student {//构造方法constructor(realname, age, major) {//调用父类的方法,相当于Student.call(this,realname, age)super(realname, age);this.major = major;}//子类的成员属性program(type) {console.log("我会编程的语言是:" + type);}// 子类对父类方法的重写play(str) {console.log("我只学习,不玩" + str);}}//实例化对象const It1 = new ItStudent("张三", 20, "大数据");console.log(It1.realname);It1.play("游戏"); //我只学习,不玩游戏</script>

说明:Class 可以通过extends关键字实现继承,让子类继承父类的属性和方法。ES6 规定,子类必须在constructor()方法中调用super(),否则就会报错。

4> getter和setter设置

<script>// get 和 setclass Phone {// get 监测动态属性的变化get price() {console.log("价格属性被读取了");return "iloveyou";}// set 对更改设置的值做判断,合法怎么办,不合法怎么办set price(newVal) {console.log("价格属性被修改了");}}//实例化对象let s = new Phone();console.log(s.price);//输出price属性,只要读取,就会执行get后面对应的函数代码,函数的返回值就是属性的返回值s.price = "9.9";//更改price属性,只要更改,就会执行set后面对应的函数代码</script>

18、模块化(module)

模块化是指将一个大的程序文件,拆分成许多小的文件,然后将小文件组合起来。

1、模块化的优势

1) 防止命名冲突

2) 代码复用

3) 高维护性,可以对某些模块化升级

2、ES6 模块化语法

模块功能主要由两个命令构成:export 和import。

export 命令用于规定模块的对外接口,对外暴露

import 命令用于输入其他模块提供的功能 ,引入暴露的文件

1> 暴露语法汇总

(1)、分别暴露

//m1.js  分别暴露
export let school = 'bdqn';
export function teach() {console.log("我们可以教给你开发技能");
}
(2)、统一暴露
// m2.js  统一暴露
let school = 'bdqn';
function findJob(){console.log("我们可以帮助你找工作!!");
}
export {school, findJob};
(3)、默认暴露
//m3.js 默认暴露
export default {school: 'bdqn',change: function(){console.log("我们可以改变你!!");}
}

exportexport default的区别(面试题)

1、两者均可用于导出常量、函数、文件、模块;

2、在一个文件中可以多次使用export,但是export default只能用一次;

3、通过export输出的,在import导入时需要使用{},export default不需要;

4、export与export default不可同时使用;

2> 引入暴露文件语法
(1)、通用方式
 //1. 通用的导入方式//引入 m1.js 模块内容import * as m1 from './js/m1.js'//引入 m2.js 模块内容import * as m2 from "./js/m2.js";//引入 m3.jsimport * as m3 from "./js/m3.js";console.log(m1);
(2)、解构附值
//2. 解构赋值形式的导入方式import { school, teach } from "./js/m1.js";//用别名import {school as yyzx, findJob} from "./js/m2.js";import {default as m3} from "./js/m3.js";
(3)、简易形式
    //3. 简便形式的导入方式   针对默认暴露import m3 from "./js/m3.js";
3> 建立入口文件形式
// app.js  入口文件
//模块引入
import * as m1 from "./m1.js";
import * as m2 from "./m2.js";
import * as m3 from "./m3.js";console.log(m1);
console.log(m2);
console.log(m3);
<!--index.html  引入 入口文件 --><script src="./js/app.js" type="module"></script>

相关文章:

ES6 特性全面解析与应用实践

1、let let 关键字用来声明变量&#xff0c;使用let 声明的变量有几个特点&#xff1a; 1) 不允许重复声明 2) 块儿级作用域 3) 不存在变量提升 4) 不影响作用域链 5) 暂时性死区 6&#xff09;不与顶级对象挂钩 在代码块内&#xff0c;使用let命令声明变量之前&#x…...

Qt跨线程信号槽调用:为什么信号不能像普通函数那样调用

1. 信号与槽机制的基本原理 在 Qt 中&#xff0c;信号与槽机制是一种事件驱动的通信方式&#xff0c;用于对象之间的解耦交互。其关键特点如下&#xff1a; 信号不能直接调用 信号只是一个声明&#xff0c;并没有实际的函数实现。它们通过 emit 关键字在对象内部被触发&…...

Zookeeper(79)如何进行Zookeeper的监控?

对 Zookeeper 进行监控是确保其高可用性和性能的关键步骤。监控 Zookeeper 通常包括以下几个方面&#xff1a; 健康检查&#xff1a;检查 Zookeeper 节点是否在线。性能指标&#xff1a;监控关键性能指标&#xff0c;如请求延迟、事务处理量等。日志监控&#xff1a;监控 Zook…...

【江科大STM32】TIM输出比较-PWM功能(学习笔记)

一、PWM驱动LED呼吸灯 接线图&#xff1a; PWM的初始化: 具体步骤&#xff1a; ①RCC开启时钟&#xff08;把要用的TIM外设和GPIO外设时钟都打开&#xff09; ② 配置时基单元&#xff0c;包括前面的时钟源选择 ③配置输出比较单元&#xff0c;里面包括CCR的值&#xff…...

playbin之autoplug_factories源码剖析

一、autoplug_factories_cb /* Called when we must provide a list of factories to plug to pad with caps.* We first check if we have a sink that can handle the format and if we do, we* return NULL, to expose the pad. If we have no sink (or the sink does not…...

Spring Cloud之注册中心之Nacos的使用

目录 Naacos 服务注册/服务发现 引⼊Spring Cloud Alibaba依赖 引入Nacos依赖 引入Load Balance依赖 配置Nacos地址 服务端调用 启动服务 Naacos Nacos是Spring Cloud Alibaba的组件, Spring Cloud Alibaba遵循Spring Cloud中定义的服务注册, 服务发现规范. 因此使⽤Na…...

React antd的datePicker自定义,封装成组件

一、antd的datePicker自定义 需求&#xff1a;用户需要为日期选择器的每个日期单元格添加一个Tooltip&#xff0c;当鼠标悬停时显示日期、可兑换流量余额和本公会可兑流量。这些数据需要从接口获取。我需要结合之前的代码&#xff0c;确保Tooltip正确显示&#xff0c;并且数据…...

【tplink】校园网接路由器如何单独登录自己的账号,wan-lan和lan-lan区别

老式路由器TPLINK&#xff0c;接入校园网后一人登录&#xff0c;所有人都能通过连接此路由器上网&#xff0c;无法解决遂上网搜索&#xff0c;无果&#xff0c;幸而偶然看到一个帖子说要把信号源网线接入路由器lan口&#xff0c;开启新世界。 一、wan-lan&#xff0c;lan-lan区…...

散户情绪周期模型(情绪影响操作)

目录 一、个股上涨阶段情绪演化二、个股下跌阶段情绪演化三、底部震荡阶段情绪演化四、情绪观察与操作工具箱1. 情绪自测量表&#xff08;每日收盘后记录&#xff09;2. 情绪-指标对照表 五、高阶情绪管理技巧1.认知重构训练2.生理指标监控&#xff08;需配合智能手表&#xff…...

对比Grok3 普通账户与 30 美元 Super 账户:默认模式、Think 和 DeepSearch 次数限制以及如何升级

面对这个马斯克旗下的"最聪明"的人工智能&#xff0c;很多人都不知道他们的基本模式&#xff0c;本期将从几个方面开始说明&#xff1a; Grok3的背景与功能 账户类型及其详细背景 使用限制 使用限制对比表 如何充值使用 Super 账户 纯干货&#xff0c;带你了解…...

小程序Three Dof识别 实现景区AR体验

代码工程 GitCode - 全球开发者的开源社区,开源代码托管平台 dof...

主流Linux发行版优缺点整理及对比指南(文末附表格)

Linux发行版种类繁多&#xff0c;各有其设计理念和适用场景。本文整理常见发行版的优缺点&#xff0c;并附对比表格&#xff0c;帮助用户根据需求选择最适合的系统。 1. Ubuntu 定位&#xff1a;适合新手的通用型桌面/服务器系统优点&#xff1a; 安装简单&#xff0c;社区支持…...

用大白话解释搜索引擎Elasticsearch是什么,有什么用,怎么用

Elasticsearch是什么&#xff1f; Elasticsearch&#xff08;简称ES&#xff09;就像一个“超级智能的图书馆管理系统”&#xff0c;专门帮你从海量数据中快速找到想要的信息。它底层基于倒排索引技术&#xff08;类似书籍的目录页&#xff09;&#xff0c;能秒级搜索和分析万…...

坐标变换及视图变换和透视变换(相机透视模型)

文章目录 2D transformationScaleReflectionShear&#xff08;切变&#xff09;Rotation around originTranslationReverse变换顺序复杂变换的分解 齐次坐标&#xff08;Homogenous Coordinates&#xff09;3D transformationScale&TranslationRotation Viewing / Camera t…...

C# 基于.NET Framework框架WPF应用程序-MQTTNet库实现MQTT消息订阅发布

C# 基于.NET Framework框架WPF应用程序-MQTTNet库实现MQTT消息订阅发布 MQTT简述MQTTNet简述创建项目&#xff08;基于.NET Framework框架&#xff09;安装MQTTNet库项目源码运行效果 MQTT简述 mqtt官网 MQTTNet简述 MQTTnet MQTTnet 是一个强大的开源 MQTT 客户端库&#…...

Python实现视频播放器

Python实现视频播放器 Python实现视频播放器&#xff0c;在如下博文中介绍过 Python实现本地视频/音频播放器https://blog.csdn.net/cnds123/article/details/137874107 Python简单GUI程序示例 中 “四、视频播放器” https://blog.csdn.net/cnds123/article/details/122903…...

介绍一款飞算JavaAI编程工具,集成到idea,图文并茂

飞算的插件下载地址&#xff0c;里边也有安装步骤&#xff1a; JavaAI 下载 从file-》setting-》plugin&#xff0c;然后走图中所示 选择从磁盘安装插件&#xff1a;找到下载好的压缩包然后进行idea重启 根据提示模块可以生成代码&#xff0c;就是需要等待&#xff0c;后期不…...

【大数据】Spark Executor内存分配原理与调优

【大数据】Spark Executor内存管理与调优 Executor内存总体布局 统一内存管理 堆内内存 (On-heap Memory) 堆外内存 (Off-heap Memory) Execution 内存和 Storage 内存动态占用机制 任务内存管理&#xff08;Task Memory Manager&#xff09; 只用了堆内内存的示例 用了…...

Python 课堂点名桌面小程序

一、场景分析 闲来无事&#xff0c;老婆说叫我开发一个课堂点名桌面小程序&#xff0c;给她在课堂随机点名学生问问题。 人生苦短&#xff0c;那就用 Python 给她写一个吧。 二、依赖安装 因为要用到 excel&#xff0c;所以安装两个依赖&#xff1a; pip install openpyxl…...

配置Spring Boot中的Jackson序列化

配置Spring Boot中的Jackson序列化 在开发基于Spring Boot的应用程序时&#xff0c;Jackson是默认的JSON序列化和反序列化工具。它提供了强大的功能&#xff0c;可以灵活地处理JSON数据。然而&#xff0c;Jackson的默认行为可能无法完全满足我们的需求。例如&#xff0c;日期格…...

Rust学习总结之-match

Rust 有一个叫做 match 的极为强大的控制流运算符&#xff0c;它允许我们将一个值与一系列的模式相比较&#xff0c;并根据相匹配的模式执行相应代码。模式可由字面量、变量、通配符和许多其他内容构成。 一&#xff1a;match定义 可以把 match 表达式想象成某种硬币分类器&a…...

实践教程:使用DeepSeek实现PDF转Word的高效方案

&#x1f388;Deepseek推荐工具 PDF文件因其跨平台、格式稳定的特性被广泛使用&#xff0c;但在内容编辑场景中&#xff0c;用户常需将PDF转换为可编辑的Word文档。传统的付费工具&#xff08;如Adobe Acrobat&#xff09;或在线转换平台存在成本高、隐私风险等问题。本文将使…...

鸿蒙 ArkUI 实现 2048 小游戏

2048 是一款经典的益智游戏&#xff0c;玩家通过滑动屏幕合并相同数字的方块&#xff0c;最终目标是合成数字 2048。本文基于鸿蒙 ArkUI 框架&#xff0c;详细解析其实现过程&#xff0c;帮助开发者理解如何利用声明式 UI 和状态管理构建此类游戏。 一、核心数据结构与状态管理…...

az devops login报错:Failed to authenticate using the supplied token.

PowerShell&#xff0c;az devops login报错&#xff1a; Failed to authenticate using the supplied token. 检查了一下PAT token是对的。 检查命令&#xff1a; az devops login --organization https://dev.azure.com/xxxxxxxx/ 乍一看好像没问题问题&#xff0c;然后想…...

C ++ 静态存储区+堆空间

静态存储区 特点&#xff1a; 1&#xff1a;生命周期很长&#xff0c;main函数开始之前就存在&#xff0c;main函数结束&#xff0c;才结束 2&#xff1a;同名变量的管理&#xff0c;与栈不一样(重名变量前提&#xff0c;作用域一样)&#xff1a; 栈&#xff1a;遇到重名变…...

gtest 和 gmock讲解

Google Test&#xff08;gtest&#xff09;和 Google Mock&#xff08;gmock&#xff09;是 Google 开发的用于 C 的测试框架和模拟框架&#xff0c;以下是对它们的详细讲解&#xff1a; Google Test&#xff08;gtest&#xff09; 简介 Google Test 是一个用于 C 的单元测试框…...

docker的下载与使用(一)

本文默认使用linux系统以及会linux的基本指令&#xff0c;windows下安装docker较为繁琐 docker是什么 Docker 是一个开源的应用容器引擎&#xff0c;基于go 语言并遵从 Apache2.0 协议开源。 Docker 可以让开发者打包他们的应用以及依赖包到一个轻量级、可移植的容器中&…...

鸿蒙HarmonyOS NEXT开发:组件-样式-基础 2

// 1 // 2 ArkUI 基本语法 // 方舟开发框架(简称:ArkUI),是一套 构建HarmonyOS应用 界面 的框架。 // 构建页面的最小单位就是 "组件"。 // 组件名(参数) { // 内容 // } // .属性1() // .属性2() // .属性N() import text from @ohos.graphics.text // @En…...

如何理解数据库的几种事务隔离级别?以及如何理解脏读、不可重复度、幻读?

在多用户并发访问数据库时&#xff0c;数据库系统需要通过事务隔离级别来控制不同事务之间的相互影响。不同的隔离级别可以避免或减少在并发环境下可能出现的数据不一致或冲突。常见的事务隔离级别有四种&#xff1a;读未提交&#xff08;Read Uncommitted&#xff09;、读已提…...

计算机网络基础简答题资料(对口高考)

1、什么是计算机网络&#xff1f;计算机网络的功能有哪些&#xff1f; 答案&#xff1a;计算机网络&#xff0c;是指将分布在不同地理位置、具有独立功能的多台计算机及其外围设备&#xff0c;通过通信设备和通信线路连接起来&#xff0c;在网络操作系统、网络管理软件及网络通…...

在docker容器中运行vllm部署deepseek-r1大模型

# 在本地部署python环境 cd /app/ python -m venv myenv # 激活虚拟环境 source /app/myenv/activate # 要撤销激活一个虚拟环境&#xff0c;请输入: deactivate# 进入虚拟环境安装modelscope pip install modelscope# 下载大模型&#xff08;7B为例&#xff09; modelscope do…...

HeidiSQL如何替换代码中的某些信息

1.SQL代码里的某些内容&#xff0c;比如2025年这个日期信息&#xff0c;我想替换成2024年的&#xff0c;按照:“搜索”---“替换文本”然后按照图片上的步骤来就可以了&#xff0c;特别是在sql代码有几百行甚至几千行的时候使用 2.SQL代码的表格对象中的数据如何一次性把某个内…...

Wireshark 插件开发实战指南

Wireshark 插件开发实战指南 环境搭建流程图 #mermaid-svg-XpNibno7BIyfzNn5 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-XpNibno7BIyfzNn5 .error-icon{fill:#552222;}#mermaid-svg-XpNibno7BIyfzNn5 .error-t…...

【大模型➕知识图谱】大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式

【大模型➕知识图谱】大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式 大模型结合医疗知识图谱:解锁智能辅助诊疗系统新范式引言一、系统架构1.1 系统架构图1.2 架构模块说明1.2.1 用户输入1.2.2 大模型(语义理解与意图识别)1.2.3 Agent(问题解析与任务分配)1.2.4 问…...

大模型应用落地具体规划方案

摘要 本篇文章主要探讨大模型应用落地的具体规划方案&#xff0c;包含六点内容的分享&#xff0c;分别是&#xff1a; 大模型本地部署架构 大模型应用交互场景 基于阿里云RAG 项目的实现方案 大模型推荐落地场景方案 大模型应用落地发展规划 大模型开源架构选型推荐 在阅…...

【Qt】MVC设计模式

目录 一、搭建MVC框架 二、创建数据库连接单例类SingleDB 三、数据库业务操作类model设计 四、control层&#xff0c;关于model管理类设计 五、view层即为窗口UI类 一、搭建MVC框架 里面的bin、lib、database文件夹以及sqlite3.h与工程后缀为.pro文件的配置与上次发的文章…...

python量化交易——金融数据管理最佳实践——qteasy创建本地数据源

文章目录 qteasy金融历史数据管理总体介绍本地数据源——DataSource对象默认数据源查看数据表查看数据源的整体信息最重要的数据表其他的数据表 从数据表中获取数据向数据表中添加数据删除数据表 —— 请尽量小心&#xff0c;删除后无法恢复&#xff01;&#xff01;总结 qteas…...

深入探索Python机器学习算法:监督学习(线性回归,逻辑回归,决策树与随机森林,支持向量机,K近邻算法)

文章目录 深入探索Python机器学习算法&#xff1a;监督学习一、线性回归二、逻辑回归三、决策树与随机森林四、支持向量机五、K近邻算法 深入探索Python机器学习算法&#xff1a;监督学习 在机器学习领域&#xff0c;Python凭借其丰富的库和简洁的语法成为了众多数据科学家和机…...

word转换为pdf后图片失真解决办法、高质量PDF转换方法

1、安装Adobe Acrobat Pro DC 自行安装 2、配置Acrobat PDFMaker &#xff08;1&#xff09;点击word选项卡上的Acrobat插件&#xff0c;&#xff08;2&#xff09;点击“首选项”按钮&#xff0c;&#xff08;3&#xff09;点击“高级配置”按钮&#xff08;4&#xff09;点…...

【MATLAB例程】三维下的IMM(交互式多模型),模型使用CV(匀速)和CA(匀加速)

给出三维下的交互式多模型&#xff08;IMM&#xff09;matlab例程&#xff0c;模型使用匀速运动CV和匀加速运动CA&#xff0c;滤波使用EKF&#xff08;扩展卡尔曼滤波&#xff09; 文章目录 代码运行结果程序结构 代码讲解模型定义&#xff1a;轨迹生成&#xff1a;IMM核心流程…...

千峰React:Hooks(下)

useLayoutEffect useLayoutEffect在useEffect之前触发 这样会闪屏&#xff0c;因为是异步的&#xff0c;两次都渲染了 import {useEffect,useState } from react;function App() {const [msg,setMsg] useState(hello App)useEffect(() > {setMsg(hello useEffect)});retu…...

突破网络壁垒:实现 Mac SSH 访问 Windows WSL Ubuntu 的最佳实践20250301

突破网络壁垒&#xff1a;实现 Mac SSH 访问 Windows WSL Ubuntu 的最佳实践 背景与痛点 在现代开发环境中&#xff0c;开发者通常会面临不同操作系统之间的协同工作。例如&#xff1a; 主要开发环境位于 Windows 的 WSL Ubuntu 子系统需要从局域网内的 Mac 设备进行远程访问…...

【开源-鸿蒙土拨鼠大理石系统】鸿蒙 HarmonyOS Next App+微信小程序+云平台

✨本人自己开发的开源项目&#xff1a;土拨鼠充电系统 ✨踩坑不易&#xff0c;还希望各位大佬支持一下&#xff0c;在GitHub给我点个 Start ⭐⭐&#x1f44d;&#x1f44d; ✍GitHub开源项目地址&#x1f449;&#xff1a;https://github.com/lusson-luo/HarmonyOS-groundhog-…...

RAG 阿里云

RAG-阿里云Spring AI Alibaba官网官网 RAG-阿里云Spring AI Alibaba官网官网 AI应用跑起来&#xff0c;取消一下航班的操作666...

python -ssh学习

def exe_sshcmd(ip,username,userpswd,port,cmd): """ 功能&#xff1a;SSH登录到指定设备&#xff0c;并执行对应的命令 入参&#xff1a;前四项为ssh登录shell的ip和port&#xff0c;具备管理员权限的用户名和密码&#xff0c; cmd可以…...

【Java学习】内部类

面向对象系列六 一、类级别 1.静态成员 2.非静态成员与方法 二、类的创建与成员管理 1.类的创建 2.类的成员管理 三、常见的内部类 1.非静态内部类 2.静态内部类 3.匿名内部类 4.局部内部类 一、类级别 1.1静态成员 静态成员是类级别的是能一路直属都是在类层面的&…...

养生,开启健康生活之门

在这个快节奏的时代&#xff0c;人们在忙碌奔波中&#xff0c;往往忽略了自身健康。养生保健&#xff0c;不再是老年人的专属&#xff0c;而是各个年龄段维持良好生活状态的关键&#xff0c;它是我们开启健康生活的一把钥匙。 规律作息是养生的基石。人体就像一台精密的仪器&am…...

1-3压缩命令

文章目录 1. tar1.1 压缩&#xff08;.tar.gz .tgz .tar.bz2 &#xff09;1.2 解压缩(.tar.gz .tgz .tar.bz2 ) 2.zip2.1 压缩(.zip)2.2 解压缩 3.xz3.1 压缩&#xff08;.tar.xz&#xff09;3.2 解压缩 1. tar 1.1 压缩&#xff08;.tar.gz .tgz .tar.bz2 &#xff09; c…...

Dify使用和入门

第一步&#xff1a;了解 Dify 在开始之前&#xff0c;先简单了解一下 Dify 是什么&#xff1a; Dify 是一个开源的 LLM 应用开发平台&#xff0c;专注于帮助开发者快速构建生产级的生成式 AI 应用。它支持知识库集成、RAG&#xff08;检索增强生成&#xff09;技术、复杂工作…...

AcWing 5933:爬楼梯 ← 递归 / 递推 / 高精度

【题目来源】 https://www.acwing.com/problem/content/5936/ 【题目描述】 树老师爬楼梯&#xff0c;他可以每次走 1 级或者 2 级&#xff0c;输入楼梯的级数&#xff0c;求不同的走法数。 例如&#xff1a;楼梯一共有 3 级&#xff0c;他可以每次都走一级&#xff0c;或者第…...