ES6基础内容
ES 全称 EcmaScript ,是脚本语言的规范,而平时经常编写的 JavaScript 是 EcmaScript 的一种实现,所以 ES 新特性其实指的就是 JavaScript 的新特性。
一、 let变量声明和声明特性
1.1 变量声明
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let a;let b,c,d;let e=521;let f=100,g='iloveyou',h=[];</script>
</body>
</html>
1.2 声明特性
1.2.1 变量不能重复声明
当用let声明两个变量名一样时,会报错。
1.2.2 块级作用域
es5作用域分为:
- 全局
- 函数
- eval
es6引入新的作用域:块级作用域
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>{let name='小羊苏西';}console.log(name);</script>
</body>
</html>
在块之外读取不到该变量,如下:
将let改为var后,可读取到变量:
主要用于:if else for while 后的{}中。
1.2.3 不存在变量提升
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>console.log(age);var age=18;console.log(addr);let addr='山东省'</script>
</body>
</html>
var 声明的变量存在变量提升,可在声明变量之前使用该变量而不会报错,而
let 声明的变量不存在变量提升,在声明变量之前使用该变量会报错。
var 声明的变量相当于在一开始就声明了该变量,只是没有赋值,故输出undefined。
1.2.4 不影响作用域链
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>{let phone=12345;function fun(){console.log(phone);}fun();}</script>
</body>
</html>
在块级作用域中,可正常按照作用域来执行。
1.3 案例
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h3>点击切换颜色</h3><div class="box"><div class="item"></div><div class="item"></div><div class="item"></div></div><script>//获取div元素let items=document.getElementsByClassName('item');//遍历并绑定事件for(var i=0;i<items.length;i++){items[i].onclick = function(){//修改当前元素的背景颜色items[i].style.background='pink';}}</script><style>.box{width: 350px;display: flex;justify-self: start;}.item{width: 100px;height: 70px;margin-left: 5px;border: 1px solid blue;}</style>
</body>
</html>
当使用 var 来定义 i 时,当执行点击函数内部的 items[i] 时,会向外读取 i 的值,而读取到的 i 为3,会报错,可使用 this.style.background='pink' 来实现该效果。
改为 let 来声明,由于具有块级作用域,读取到的 i 可为 0,1,2,不会报错。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><h3>点击切换颜色</h3><div class="box"><div class="item"></div><div class="item"></div><div class="item"></div></div><script>//获取div元素let items=document.getElementsByClassName('item');//遍历并绑定事件for(let i=0;i<items.length;i++){items[i].onclick = function(){//修改当前元素的背景颜色items[i].style.background='pink';}}</script><style>.box{width: 350px;display: flex;justify-self: start;}.item{width: 100px;height: 70px;margin-left: 5px;border: 1px solid blue;}</style>
</body>
</html>
效果图如下:
二、const声明常量和特点
2.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const NAME='小羊苏西';</script>
</body>
</html>
2.2 特点
-
一定要赋初始值;
-
一般常量使用大写;
-
常量的值不能修改;
-
块级作用域;
-
对于数组和对象的元素修改,不算对常量的修改,不会报错。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const NAME=['张三','李四'];NAME.push('赵五');</script>
</body>
</html>
对数组和对象的元素修改,并不影响常量指向的地址,不会报错。
三、变量的解构赋值
ES6 允许按照一定模式从数组和对象中提取值,对变量进行赋值。
3.1 数组的解构
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const TF=['王俊凯','王源','易烊千玺'];let [no1,no2,no3]=TF;console.log(no1);console.log(no2);console.log(no3);</script>
</body>
</html>
3.2 对象的解构
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const WJK={name:'王俊凯',age:25,talent:function(){console.log('擅长唱歌跳舞');}}let {name,age,talent}=WJK;console.log(name);console.log(age);talent();</script>
</body>
</html>
四、模板字符串
es5声明字符串方式:' '," ";
es6新增:` `
4.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let str=`我是一个字符串`;console.log(str,typeof(str));</script>
</body>
</html>
4.2 特点
4.2.1 内容中可以直接出现换行符
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let str=`<ul><li>王俊凯</li><li>王源</li><li>易烊千玺</li></ul>`;</script>
</body>
</html>
` `使用换行符时并不会出现错误
' '和" "会报错。
4.2.2 字符拼接
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let name='王俊凯';let res=`${name}擅长唱歌跳舞`;console.log(res);</script>
</body>
</html>
五、对象简化写法
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let name=`小田`;let change=function(){console.log('我们可以改变');}const res={//name:namename,//change:changechange,// fun:function(){// console.log("我们在学校");// }fun(){console.log("我们在学校");}}console.log(res);</script>
</body>
</html>
六、箭头函数
6.1 声明格式
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let fun=(a,b)=>{return a+b;}let res=fun(1,2);console.log(res);</script>
</body>
</html>
6.2 特点
6.2.1 this是静态的
始终指向函数声明时所在作用域下的this值
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function getName(){console.log(this.name);}let getName1=()=>{console.log(this.name);}//设置 window 对象的 name 属性window.name='小田';const temp={name:'xiaotian'}//直接调用getName();getName1();console.log("————————")//call方法调用getName.call(temp);getName1.call(temp);</script>
</body>
</html>
call方法可以改变函数内部this值
6.2.2 不能作为构造实例化对象
6.2.3 不能使用 arguments 变量
6.2.4 箭头函数简写
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//省略小括号,当形参有且只有一个的时候let add= n =>{return n+n;}console.log(add(9));//省略花括号,当代码体只有一条语句的时候,此时return必须省略//语句执行结果就是函数返回值let pow=(n)=>n*n;console.log(pow(9));</script>
</body>
</html>
七、函数参数默认值
ES6允许给参数参数赋值初始值
7.1 形参初始值
具有默认的参数,一般位置要靠后
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function add(a,b,c){return a+b+c;}let res=add(1,2,3);console.log(res);//当c没有传值时,为undefined,相加为NaNlet res1=add(1,2);console.log(res1);function add1(a,b,c=10){return a+b+c;}//当c有传值时,用所传的值覆盖初始值let res2=add1(1,2,3);console.log(res2);//当c没有传值时,用初始值let res3=add1(1,2);console.log(res3);</script>
</body>
</html>
7.2 与解构赋值结合
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function connect({host="127.0.0.1",username,password,port}){console.log(host);console.log(username);console.log(password);console.log(port);}connect({host:'localhost',username:'root',password:'root',port:3306})//无host值,使用默认值·connect({username:'tian',password:123456,port:8080})</script>
</body>
</html>
八、rest参数
ES5获取实参方式:
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function data(){console.log(arguments);}data('王俊凯','王源','易烊千玺');</script>
</body>
</html>
ES6引入 rest 参数,用于获取参数的实参,来替代 arguments。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function data(...args){console.log(args);}data('王俊凯','王源','易烊千玺');//rest参数必须要放到参数最后function fn(a,b,...args){console.log(a);console.log(b);console.log(args);}fn(1,2,3,4,5,6);</script>
</body>
</html>
arguments 获取的是对象,而 rest 参数类型获取的是数组形式。
九、扩展运算符
... 扩展运算符能将数组转换成逗号分隔的参数序列
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const tfboys=['王俊凯','王源','易烊千玺'];// =>'王俊凯','王源','易烊千玺'function fn(){console.log(arguments);}fn(tfboys);console.log('----------')fn(...tfboys);// => fn('王俊凯','王源','易烊千玺')</script>
</body>
</html>
9.1 应用
9.1.1 数组的合并
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const heze=['曹县','定陶'];const taian=['岱岳区','泰山区'];const shandong=heze.concat(taian);console.log(shandong);const shandong1=[...heze,...taian];console.log(shandong1);</script>
</body>
</html>
9.1.2 数组的克隆
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const arr=['a','b','c'];const arr1=[...arr];console.log(arr1);</script>
</body>
</html>
9.1.3 伪数组转换成真正数组
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><div></div><div></div><div></div><script>const divs=document.querySelectorAll('div');const divArr=[...divs];console.log(divs);console.log(divArr);</script>
</body>
</html>
十、Symbol
ES6 引入了一种新的原始数据类型 Symbol ,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型。
Symbol 特点
- Symbol 的值是唯一的,用来解决命名冲突的问题
- Symbol值不能与其他数据进行运算
- Symbol定义的对象属性不能使用 for..in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名
JS七种数据类型:
undefined
string 、symbol
object
null 、number·
boolean
10.1 symbol创建
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let s=Symbol();console.log(s,typeof s);//tian相当于一个名称或注释,描述字符串let s1=Symbol('tian');let s2=Symbol('tian');console.log(s1===s2);let s3=Symbol.for('tian');let s4=Symbol.for('tian');console.log(s3===s4);//不能与其他数据进行运算let res=s+100;let res1=s>100;let res2=s+s;</script>
</body>
</html>
10.2 symbol使用
给对象添加属性和方法,表示独一无二的
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>let game={name:'王者荣耀',up:'我上升到王者了',down:'我下降到砖石了',};//当想向game对象添加方法 up down// game.up=function(){},当game对象内部未知,使用可能有冲突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>
</body>
</html>
10.3 symbol内置属性
Symbol.hasInstance | 当其他对象使用 instanceof 运算符,判断是否为该对象的实例时,会调用这个方法 |
Symbol.isConcatSpreadable | 对象的 Symbol.isConcatSpreadable 属性等于的是一个布尔值,表示该对象用于 Array:prototype.concat()时,是否可以展开。 |
Symbol.unscopables | 该对象指定了使用 with 关键字时,哪些属性会被 with环境排除。 |
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.species | 创建衍生对象时,会使用该属性。 |
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>class Person{static [Symbol.hasInstance](param){console.log(param);console.log(1111111);}}let o={};console.log(o instanceof Person);console.log('------------');const arr=[1,2,3];const arr1=[4,5,6];console.log(arr.concat(arr1));arr1[Symbol.isConcatSpreadable]=false;console.log(arr.concat(arr1));</script>
</body>
</html>
十一、迭代器
迭代器(Iterator)是一种接口,为各种不同的数据结构提供统一的访问机制。任何数据结构只要部署lterator接口,就可以完成遍历操作。
ES6 创造了一种新的遍历命令 for..of 循环,lterator 接口主要供 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>Document</title>
</head>
<body><script>const tfboys=['王俊凯','王源','易烊千玺'];//for...of 中表 键值for(let v of tfboys){console.log(v);}//for...in 中表 下标for(let v in tfboys){console.log(v);}</script>
</body>
</html>
工作原理
- 创建一个指针对象,指向当前数据结构的起始位置
- 第一次调用对象的next 方法,指针自动指向数据结构的第一个成员
- 接下来不断调用 next 方法,指针一直往后移动,直到向最后一个成员
- 每调用 next方法返回一个包含 value 和 done 属性的对象
需要自定义遍历数据的时候,要想到迭代器。
11.1 自定义遍历数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const clazz={name:'1班',stus:['张三','李四','王五'],[Symbol.iterator](){//索引变量let index=0;let _this=this;return{next:function(){if(index<_this.stus.length){const res={value:_this.stus[index],done:false};//下标自增index++;//返回结果return res;}else{return {value:undefined,done:true};}}};}}for(let v of clazz){console.log(v);}</script>
</body>
</html>
十二、生成器
生成器函数其实是一种特殊的函数,用于异步编程
12.1 声明与调用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//声明function * gen(){console.log("hello tian")}//调用let iterator=gen();iterator.next();</script>
</body>
</html>
生成器函数可用 yield 函数代码的分隔符
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function * gen(){console.log(111);yield '一只没有耳朵';console.log(222);yield '一只没有尾巴';console.log(333);yield '真奇怪';console.log(444);}function * gen1(){yield '一只没有耳朵';yield '一只没有尾巴';yield '真奇怪';}//调用let iterator=gen();//只输出每个模块中的输出内容iterator.next();iterator.next();iterator.next();iterator.next();console.log("---------------");let iterator1=gen1();//会输出返回的value值console.log(iterator1.next());console.log(iterator1.next());console.log(iterator1.next());console.log(iterator1.next());console.log("---------------");for(let v of gen1()){console.log(v);}</script>
</body>
</html>
12.2 参数传递
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function * gen(arg){console.log(arg);let one=yield 111;console.log(one);let two=yield 222;console.log(two);let three=yield 333;console.log(three);}//arg接受AAAlet iterator=gen('AAA');//输出第一模块间语句,并且输出第一条yieldconsole.log(iterator.next());//next方法可以传入实参,作为上一条yield语句的返回值console.log(iterator.next('BBB'));console.log(iterator.next('CCC'));console.log(iterator.next('DDD'));</script>
</body>
</html>
12.3 案例
1s后控制台输出111,2s后输出222,3s后输出333。
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//回调地狱,此方法不建议setTimeout(()=>{console.log(111);setTimeout(()=>{console.log(222);setTimeout(()=>{console.log(333);},3000)},2000)},1000)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>
模拟获取 用户数据 订单数据 商品数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>function getUsers(){setTimeout(()=>{let data='用户数据';iterator.next(data);},1000);}function getOders(){setTimeout(()=>{let data='订单数据';iterator.next(data);},1000);}function getGoods(){setTimeout(()=>{let data='商品数据';iterator.next(data);},1000);}function * gen(){let users=yield getUsers();console.log(users);let oders=yield getOders();console.log(oders);let goods=yield getGoods();console.log(goods);}let iterator=gen();iterator.next();</script>
</body>
</html>
十三、Promise
13.1 基本使用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败const p=new Promise(function(resolve,reject){setTimeout(function(){let data='用户数据';resolve(data);},1000);})//参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行p.then(function(value){console.log(value);},function(reason){console.error(reason);})</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>//实例化Promise对象,参数为函数,函数的参数resolve表示成功,reject表示失败const p=new Promise(function(resolve,reject){setTimeout(function(){let err='数据读取失败';reject(err);},1000);})//参数为两个函数,第一个函数对应resolve成功执行,第二个函数对应reject失败执行p.then(function(value){console.log(value);},function(reason){console.error(reason);})</script>
</body>
</html>
调用 resolve 后,p 的状态变为成功,并调用 p.then() 参数中第一个函数;
调用 reject 后,p 的状态变为失败, 并调用 p.then() 参数中第二个函数。
13.2 读取文件
const fs=require('fs');
const { resourceLimits } = require('worker_threads');
//1.调用方法读取文件
fs.readFile('./静夜思.md',(err,data)=>{//如果失败,则抛出异常if(err) throw err;//如果成功,则输出内容console.log(data.toString());
});
//2.使用Promise封装
const p=new Promise(function(resolve,reject){fs.readFile("./静夜思.md",(err,data)=>{if(err) reject(err);resolve(data);});
});
p.then(function(value){console.log(value.toString());
},function(reason){console.log("读取失败!!");
})
13.3 封装AJAX请求
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const p=new Promise((reslove,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){if(xhr.status>=200 && xhr.status<300){//表示成功reslove(xhr.response);}else{//如果失败reject(xhr.status);}}}});//指定回调p.then(function(value){console.log(value);},function(reason){console.error(reason);})</script>
</body>
</html>
13.4 then方法
调用 then 方法, then 方法的返回结果是 Promise 对象,对象状态由回调函数的执行结果决定。
如果回调函数中返回的结果是 非Promise 类型的属性,状态为已完成,返回值为对象的成功的值;
是 Promise 对象,状态为已完成,返回值为 调用 resolve 或 reject 传的值;
抛出异常,状态为失败,返回值为 抛出的异常值;
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const p=new Promise((resolve,reject)=>{setTimeout(()=>{resolve("用户数据");},1000)});//返回结果为非promise对象,不写return默认为undefinedconst res=p.then(value=>{console.log(value);return 123;},reason=>{console.warn(reason);})console.log(res);</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const p=new Promise((resolve,reject)=>{setTimeout(()=>{resolve("用户数据");},1000)});//返回结果为非promise对象,不写return默认为undefinedconst res=p.then(value=>{console.log(value);return new Promise((resolve,reject)=>{resolve("ok");})},reason=>{console.warn(reason);})console.log(res);</script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const p=new Promise((resolve,reject)=>{setTimeout(()=>{resolve("用户数据");},1000)});//返回结果为非promise对象,不写return默认为undefinedconst res=p.then(value=>{console.log(value);throw "出错啦!!!";},reason=>{console.warn(reason);})console.log(res);</script>
</body>
</html>
可进行链式调用!!!
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body><script>const p=new Promise((resolve,reject)=>{setTimeout(()=>{resolve("用户数据");},1000)});p.then(value=>{},reason=>{}).then(value=>{},reason=>{});</script>
</body>
</html>
相关文章:

ES6基础内容
ES 全称 EcmaScript ,是脚本语言的规范,而平时经常编写的 JavaScript 是 EcmaScript 的一种实现,所以 ES 新特性其实指的就是 JavaScript 的新特性。 一、 let变量声明和声明特性 1.1 变量声明 <!DOCTYPE html> <html lang"en">…...

DeepSeek本地部署的一些使用体会
春节期间我也尝试了一下Deepseek的本地部署,方案选用了Ollama Chatbox或AnythingLLM。Chatbox里有很多有意思的“助手”,而AnythingLLM支持本地知识库。 网上教程很多,总的来说还是很方便的,不需要费太多脑子。甚至可以这么说&a…...

鲸鱼算法 matlab pso
算法原理 鲸鱼优化算法的核心思想是通过模拟座头鲸的捕食过程来进行搜索和优化。座头鲸在捕猎时会围绕猎物游动并产生气泡网,迫使猎物聚集。这一行为被用来设计搜索策略,使算法能够有效地找到全局最优解。 算法步骤 初始化:随机生成一…...

013-51单片机红外遥控器模拟控制空调,自动制冷制热定时开关
主要功能是通过红外遥控器模拟控制空调,可以实现根据环境温度制冷和制热,能够通过遥控器设定温度,可以定时开关空调。 1.硬件介绍 硬件是我自己设计的一个通用的51单片机开发平台,可以根据需要自行焊接模块,这是用立创…...

在Vue3 + Vite 项目中使用 Tailwind CSS 4.0
文章目录 首先是我的package.json根据官网步骤VS Code安装插件验证是否引入成功参考资料 首先是我的package.json {"name": "aplumweb","private": true,"version": "0.0.0","type": "module","s…...

Leetcode—922. 按奇偶排序数组 II【简单】
2025每日刷题(207) Leetcode—922. 按奇偶排序数组 II 实现代码 class Solution { public:vector<int> sortArrayByParityII(vector<int>& nums) {for(int i 0, j 1; i < nums.size() - 1; i 2) {// 前奇后偶if(nums[i] % 2) {w…...

一个开源 GenBI AI 本地代理(确保本地数据安全),使数据驱动型团队能够与其数据进行互动,生成文本到 SQL、图表、电子表格、报告和 BI
一、GenBI AI 代理介绍(文末提供下载) github地址:https://github.com/Canner/WrenAI 本文信息图片均来源于github作者主页 在 Wren AI,我们的使命是通过生成式商业智能 (GenBI) 使组织能够无缝访问数据&…...

使用Posix共享内存区实现进程间通信
使用Posix共享内存区实现进程间通信 使用Posix共享内存区通常涉以下步骤: 进程A 调用shm_open 创建共享内存区进程A调用ftruncate修改共享内存区大小进程A 调用mmap将共享内存区映射到进程地址空间ptrA进程A 使用ptrA对共享内存区进程更改进程B 使用shm_open打开已有共享内存…...

家政预约小程序12服务详情
目录 1 修改数据源2 创建页面3 搭建轮播图4 搭建基本信息5 显示服务规格6 搭建服务描述7 设置过滤条件总结 我们已经在首页、分类页面显示了服务的列表信息,当点击服务的内容时候需要显示服务的详情信息,本篇介绍一下详情页功能的搭建。 1 修改数据源 在…...

【C语言】指针详细解读2
1.const 修饰指针 1.1 const修饰变量 变量是可以修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量。 但是如果我们希望⼀个变量加上⼀些限制,不能被修改,怎么做呢?这就是const的作⽤。 #in…...

MongoDB 聚合
MongoDB 中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。 有点类似 SQL 语句中的 count(*)。 aggregate() 方法 MongoDB中聚合的方法使用aggregate()。 语法 aggregate() 方法的基本语法格式如下所示࿱…...

LabVIEW涡轮诊断系统
一、项目背景与行业痛点 涡轮机械是发电厂、航空发动机、石油化工等领域的核心动力设备,其运行状态直接关系到生产安全与经济效益。据统计,涡轮故障导致的非计划停机可造成每小时数十万元的经济损失,且突发故障可能引发严重安全事故。传统人…...

机器学习在地震预测中的应用
## 1. 机器学习与地震预测 地震是自然界的一种极端灾害,其发生常常给人们的生命和财产带来极大的威胁。虽然科学家们一直在寻求可靠的方法来预测地震,但由于地震预测本身的复杂性,长期以来难以取得根本性突破。然而,近年来&#x…...

总结11..
#include <stdio.h> #include <string.h> #define MAXN 1001 #define MAXM 1000001 int n, m; char maze[MAXN][MAXN]; int block[MAXN][MAXN]; // 标记每个格子所属的连通块编号 int blockSize[MAXN * MAXN]; // 记录每个连通块的大小 int dx[] {0, 0, 1, -1};…...

c++ 定点 new 及其汇编解释
(1) 代码距离: #include <new> // 需要包含这个头文件 #include <iostream>int main() {char buffer[sizeof(int)]; // 分配一个足够大的字符数组作为内存池int* p new(&buffer) int(42); // 使用 placement new…...

Linux 传输层协议 UDP 和 TCP
UDP 协议 UDP 协议端格式 16 位 UDP 长度, 表示整个数据报(UDP 首部UDP 数据)的最大长度如果校验和出错, 就会直接丢弃 UDP 的特点 UDP 传输的过程类似于寄信 . 无连接: 知道对端的 IP 和端口号就直接进行传输, 不需要建立连接不可靠: 没有确认机制, 没有重传机制; 如果因…...

springCload快速入门
原作者:3. SpringCloud - 快速通关 前置知识: Java17及以上、MavenSpringBoot、SpringMVC、MyBatisLinux、Docker 1. 分布式基础 1.1. 微服务 微服务架构风格,就像是把一个单独的应用程序开发为一套小服务,每个小服务运行在自…...

从 HTTP/1.1 到 HTTP/3:如何影响网页加载速度与性能
一、前言 在最近使用Apipost时,突然注意到了http/1.1和http/2,如下图: 在我根深蒂固的记忆中,对于http的理解还停留在TCP协议、三次握手。由于我的好奇心,于是触发了我被动“开卷”,所以有了这篇文章&…...

人工智能导论-第3章-知识点与学习笔记
参考教材3.2节的内容,介绍什么是自然演绎推理;解释“肯定后件”与“否定前件”两类错误的演绎推理是什么意义,给出具体例子加以阐述。参考教材3.3节的内容,介绍什么是文字(literal);介绍什么是子…...

游戏引擎 Unity - Unity 下载与安装
Unity Unity 首次发布于 2005 年,属于 Unity Technologies Unity 使用的开发技术有:C# Unity 的适用平台:PC、主机、移动设备、VR / AR、Web 等 Unity 的适用领域:开发中等画质中小型项目 Unity 适合初学者或需要快速上手的开…...

鼠标拖尾特效
文章目录 鼠标拖尾特效一、引言二、实现原理1、监听鼠标移动事件2、生成拖尾元素3、控制元素生命周期 三、代码实现四、使用示例五、总结 鼠标拖尾特效 一、引言 鼠标拖尾特效是一种非常酷炫的前端交互效果,能够为网页增添独特的视觉体验。它通常通过JavaScript和C…...

4 前置技术(下):git使用
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言 前言...

从零开始:用Qt开发一个功能强大的文本编辑器——WPS项目全解析
文章目录 引言项目功能介绍1. **文件操作**2. **文本编辑功能**3. **撤销与重做**4. **剪切、复制与粘贴**5. **文本查找与替换**6. **打印功能**7. **打印预览**8. **设置字体颜色**9. **设置字号**10. **设置字体**11. **左对齐**12. **右对齐**13. **居中对齐**14. **两侧对…...

解决国内服务器 npm install 卡住的问题
在使用国内云服务器时,经常会遇到 npm install 命令执行卡住的情况。本文将分享一个典型案例以及常见的解决方案。 问题描述 在执行以下命令时: mkdir test-npm cd test-npm npm init -y npm install lodash --verbose安装过程会卡在这个状态…...

DeepSeek 的含金量还在上升
大家好啊,我是董董灿。 最近 DeepSeek 越来越火了。 网上有很多针对 DeepSeek 的推理测评,除此之外,也有很多人从技术的角度来探讨 DeepSeek 带给行业的影响。 比如今天就看到了一篇文章,探讨 DeepSeek 在使用 GPU 进行模型训练…...

使用 Docker(Podman) 部署 MongoDB 数据库及使用详解
在现代开发环境中,容器化技术(如 Docker 和 Podman)已成为部署和管理应用程序的标准方式。本文将详细介绍如何使用 Podman/Docker 部署 MongoDB 数据库,并确保其他应用程序容器能够通过 Docker 网络成功连接到 MongoDB。我们将逐步…...

大模型训练(6):张量并行
0 英文缩写 Pipeline Parallelism(PP)流水线并行Tensor Parallel(TP)张量并行Data Parallelism(DP)数据并行Distributed Data Parallelism(DDP)分布式数据并行Zero Redundancy Opti…...

【力扣】238.除自身以外数组的乘积
AC截图 题目 思路 前缀积 前缀积指的是对于一个给定的数组arr,构建一个新的数组prefixProduct,其中prefixProduct[i]表示原数组从第一个元素到第i个元素(包括i)的所有元素的乘积。形式化来说: prefixProduct[0] ar…...

Nacos 的介绍和使用
1. Nacos 的介绍和安装 与 Eureka 一样,Nacos 也提供服务注册和服务发现的功能,Nacos 还支持更多元数据的管理, 同时具备配置管理功能,功能更丰富。 1.1. windows 下的安装和启动方式 下载地址:Release 2.2.3 (May …...

DeepSeek最新图像模型Janus-Pro论文阅读
目录 论文总结 摘要 1. 引言 2. 方法 2.1 架构 2.2 优化的训练策略 2.4 模型扩展 3. 实验 3.1 实施细节 3.2 评估设置 3.3 与最新技术的比较 3.4 定性结果 4. 结论 论文总结 Janus-Pro是DeepSeek最新开源的图像理解生成模型,Janus-Pro在多模态理解和文…...