1、let和const
let a / let a,b,c,d / let a=10
特点:
1、变量不能重复声明
2、作用域为块级作用域(块级,全局,函数,eval)
3、不存在变量提升
4、不影响作用域链
const a='hello'
特点:
1、要赋予初始值
2、通常大写(小写也行)
3、常量的值不能修改
4、块级作用域
5、对于数组和对象的元素进行修改不会报错(不算对常量进行修改)
2、解构赋值
1、数组结构
const array = ['云间月','林间雪','心上人']
let [a,b,c] = array //a:云间月,b:林间雪,c:心上人
2、对象结构
const ruleForm = {
page:20,
size:10,
total:100,
fun:function(){
console.log('页码20,每页10条,总数100')
}
}
let {page,size,total,fun} = ruleForm //20,10,100,和fun这个函数
fun();//可以直接调用
3、模板字符串
引入字符串的方式 `` (反引号)
特点:
1、内容中可以直接出现换行符(单引号或者双引号则不行)
2、变量拼接
let a = '魏海量'
console.log(`${a}一杯就倒`) //魏海量一杯就倒
必须使用${}的形式
4、简化对象的写法
ES6允许在大括号里面直接写入变量和函数,作为对象的属性和方法--更加简洁
let time= '12:00'
let date = function(){
return new Date()
}
const TEMP = {time,date,};//12:00,当前时间
等同于
const TEMP = {
time:time,
date:date
}
函数简化:
let fun = function(a,b){
console.log(a,b)
}
等同于
fun(a,b){
console.log(a,b)
}
5、箭头函数及其声明特点
使用 => 定义函数
原始声明:
let fun = function(a,b){console.log(a+b)}
原始调用 fun(1,2);//3
ES6声明:
let fun = (a,b) =>{console.log(a+b)}
ES6调用 fun(1,2);//3
特点:
1、this是静态的,始终指向函数声明时所在作用域下的this的值
2、不能作为构造函数实例化对象
let fun = (a,b) =>{
console.log(a+b)
}
let funs = new fun(1+2);//报错
3、不能使用arguments变量
let fun = () =>{console.log(arguments)}
fun(1,2,3);//报错 argements未定义
4、箭头函数的简写
01、省略小括号,当形参有且又有一个的时候可简写
例:let fun = (a) =>{console.log(a)}
等同于 let fun= a =>{console.log(a)}
调用:fun(1);//1
02、省略花括号,当代码体只有一条语句的时候,此时return必须省略,且语句的执行结果就是函数的返回值
例:let fun = a =>{return a+a};
等同于 let fun = a => a+a
调用:console.log(fun(1));//2
5、使用场景:
01、适合与this无关的回调、定时器、数组的方法回调
02、不适合与this有关的回调,事件的回调,对象的方法等
6、允许给函数的参数(形参)赋予初始值
原始:function add(a,b,c){return a+b+c}
add(1,2);//undefined
ES6:function add(a,b,c=3){return a+b+c}
add(1,2);//6
特点:
1、形参初始值,具有默认值的参数,一般放到后面
2、可以与解构赋值相结合
例:
function fun({name='王朱',age}){return name+'年龄'+age}
fun({age:10});//王朱年龄10
7、rest参数(用于代替arguments)
用于获取函数的实参是ES6获取实参的方式
原始:
function fun(){console.log(arguments)}
fun('周米粒,暖树,景清');//{0:‘周米粒’,1:'暖树',2:'景清'} 是一个对象
ES6:
function(...params){console.log(params)}
fun('周米粒,暖树,景清');//['周米粒,暖树,景清'] 是一个数组,可以使用数组的方法
限制:当有多个参数时,rest参数必须放到最后
例:function fun(a,b,...params){console.log(a,b,params)}
fun(1,2,3,4,5,6,7);//1,2,[3,4,5,6,7]
8、扩展运算符 ...
扩展运算符能将数组转化为逗号分割的参数序列
let params = [1,2,3]
function fun(){console.log(arguments)}
原始:fun(params);// {0:[1,2,3]} 是一个对象,只有一个参数
扩展运算符:fun(...params);//[[1,2,3]] 是一个数组,有多个参数
运用:
例:const arr = ['aa','bb']
例:const arr2 = ['dd','ee']
1、数组合并
原始:arr.concat(arr2);//['aa','bb','dd','ee']
扩展运算符 [...arr,...arr2];//['aa','bb','dd','ee']
2、数组的克隆
let arr3 = [...arr];//['aa','bb'] 如果只是值类型,则可以创建一个新的数组,如果有引用类型的话,则只是浅拷贝。
3、将伪数组转化为真正的数组(假如有三个div)
const arr = document.querySelectAll('div');//对象类型
let arrs = [...arr];//数组类型
例:转化arguments
9、Symbol(用得少)
Symbol是ES6引入的一种新的原始数据类型,表示独一无二的值;是js的第七种数据类型,类似字符串的数据类型。
特点:
1、Symbol的值是唯一的,用来解决命名冲突的问题;
2、Symbol值不能与其它数据类型进行运算;
3、Symbol定义的对象属性不能使用for...in循环遍历,但是可以使用Reflect.ownkeys获取对象的所有键名。
Symbol创建的几种方式:
1、let Sy1 = Symbol();//Symbol()
2、let Sy2 = Symbol('temp1');//Symbol('temp1')
3、let Sy3 =Symbol('temp1');//Symbol('temp1)
console.log(SY2===Sy3);//false 两个是不一样的,在内部会做区别,外部无法获知
4、let Sy4 = Symbol.for('temp2');//Symbol('tamp2')
let Sy5 = Symbol.for('temp2');//Symbol('tamp2')
console.log(SY2===Sy3);//true这样创建是一样的
Symbol的使用场景:向对象中添加属性和方法
1、方法1
let obj = {
add:()=>{},
minus:()=>{}
}
let methods = {
add:Symbol('add'),
minus:Symbol('minus')
}
obj[methods.add] = (a)=>{return a+a}
obj[methods.minus] = (a)=>{return a+a}
2、方法2
let obj= {
name:'temp',
[Symbol('fun')]:a=>return a+a
}
Symbol 还有十一个内置属性
js的数据类型:USONB
u:undefined
s:String Symbol
o:Object
n:null Number
b:Boolean
10迭代器(用得少)
迭代器是一种接口,为各种不同的数据结构提供统一的访问机制,任何数据结构只要部署interrator接口(interrator接口是对象的一个属性:Symbol.interator),就可以完成遍历操作
Es6创造一种新的遍历命令for...of循环,interator主要提供for..of循环
具备interator接口的数据(可用for...of循环遍历)
1、Array;
2、arguments;
3、Set;
4、Map;
5、String;
6、TypeArray;
7、NodeList;
例:
const arr = ['景清','暖树']
for(let i of arr){
console.log(i);//景清,暖树
}
可打印数组,在得到的数据中找到Symbol.interator这个函数 console.log(arr)
调用这个函数,然后打印返回值,可以找到next()方法 let temp = arr[Symbol.interator]()
之后可以调用next()方法 temp.next()
工作原理:
1、创建一个指针对象,指向当前结构的起始位置
2、第一次调用对象的next()方法,指针自动指向数据结构的第一个成员
3、接下来不断调用next()方法,指针一直往后移动,直到指向最后一个成员=
4、每次调用next()方法返回一个包含value和done 的属性的对象
11、生成器
是一种特殊的函数,是一种异步编程的解决方案
声明方式:函数和函数名之间加 * 号
function * fun(){console.log('hello')}
let interator = fun()
console.log(interator);//返回值是一个迭代器对象
调用:interator.next();//hello 调用的是里面的next()方法
yield语句
function * fun(){
console.log('111');
yield '第二次调用';
console.log('222');
yield '第三次调用';
console.log('333');
}
let interator = fun()
interator.next();//111
interator.next();//222
interator.next();//333
生成器函数参数
function * fun(parmas){
console.log(params);
let first = yield 1
console.log(first)
let second = yield 2
console.log(second)
}
let interator = fun('A');//获取迭代器对象
interator.next();//A {value:1,done:false}
//在调用时可以传入实参,实参作为yield语句的返回结果(第二次调用传入的实参会作为第一个yield语句的返回结果)
interator.next();//A {value:1,done:false}
//同样;第三次调用的参数会作为第二个yield语句的返回结果,以此类推
实例:
1、回调地狱函数:
function fun1(){
console.log(111)
function fun2(){
console.log(222)
function fun3(){
console.log(333)
//...
}
}
}
2、生成器函数
function fun1(){
console.log(111)
interator.next();//可传参数,作为第一个yield语句的返回值
}
function fun2(){
console.log(222)
interator.next()
}
function fun3(){
console.log(333)
interator.next()
}
function * fn(){
yield fun1()
yield fun2()
yield fun3()
}
let interator = fn()
interator.next()
12、Promise(重要)
ES6引入的异步编程的解决方案,语法上是一个构造函数,用来封装异步操作,并可以获取成功或失败的结果
基本语法:
//实例化一个Promise对象,里面的参数可以是一个异步函数(例:要封装的请求),函数有两个参数,可以随便,通常是resove和reject
const prom = new Promise(functiong(resove,reject){
function fun(){
let res = '返回结果(成功)'
resove(res)
let res2 = ‘返回结果(失败)’
reject(res2)
}
})
//回调Promise的then()方法,then()有两个参数,都是函数,函数有实参,分别是resove()返回的成功数据,和reject返回的失败数据
prom.then((res)=>{
console.log(res)
},(err)=>{
console.log(err)
})
then()方法的返回结果是一个Promise对象,对象状态由函数的执行结果决定:
1、如果回调函数中返回的结果是非Promise类型的属性,状态为成功,返回值为对象的成功的值
2、如果回调函数中返回的结果是Promise类型,则状态跟随返回的Promise的状态
then()方法可以链式调用(解决回调地狱)
catch()方法返回错误信息
例:prom.ctach(res=>{return '正确' }).catch(err=>{console.log('失败')})
13、Set
Es6提供新的数据结构Set(集合),类似于数组,但是成员都是唯一的;集合实现了interator接口,可使用扩展运算符(...)和for...of进行编辑
1、集合的属性和方法
01、size 返回集合的元素个数
02、add 添加一个元素,返回当前的集合
03、delete 删除元素,返回Boolean值
04、has 检测集合是否包含某个元素,返回Boolean值
05、clear 清空集合
2、声明方式
let s = new Set();//typeof=>Object
3、使用
let arr = [5,10,5,15]
let s2 = new Set(arr);//{5,10,15}
s2.size ;//3
s2.add(20);//{5,10,15,20}
s2.delete(2);//{10,15,20}
s2.has(5);//false
s2.clear();//{}
for(let s of s2){
console.log(s);//可获得里面的每个值
}
4、数组去重(常用)
let arr = [1,4,3,3,2,2,3,]
let arr2 = [...new Set(arr)];//[1,4,2,3]
14、Map
Map数据结构,类似于对象,是键值对的集合,但是键的范围不限于字符串,各种类型的值都可以当做键。Map实现了interator接口,可使用扩展运算符和for...of循环遍历
Map的属性和方法
01、size 返回元素个数
02、set 添加新的元素,返回当前Map
03、get 返回键名对象的键值
04、has 检测map中是否含有某个元素,返回Boolean值
05、清空集合,返回Map(0){}
声明方式:
let m = new Map()
使用:
m.set('name','周米粒');// {'name'=>'周米粒'}
m.set('fun',function(){});// {'fun'=>function(){}}
m.size;//2
m.delete('name');//{'fun'=>function(){}}
m.get('fun');//function(){}
m.clear();//map(0){}
for(let i of m){console.log(i)};//数组的形式[键,值],[键,值]
15、class
更接近传统语言的写法;通过class关键字=可以定义类,可看作是一个语法糖,大部分功能ES5可以实现,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法
//TODO 有点虚,下次还得再看看
16、数值扩展
一些方法
01、Number.isFinite();检测一个数值是否为有限数,例:
Number.isFinite(100);//返回Boolean值
02、Number.isNaN();//检测一个数是否为数字,例:
Number.isNaN(22);//返回Boolean值
03、Number.paseInt()提取整数,例:
Number.parseInt('521亲爱的姑娘');//521
04、Number.parseFloat提取浮点数,例:
Number.parseFloat('3211.1多瓦');//3211.1
05、Number.isInteger();检测一个数是否为整数,例:
Number.isInteger(6.6);//false 返回boolean值
06、Math.trunc();将数字的小数部门抹掉
Math.trunc(6.6);//6,返回抹去小数后的整数
07、Math.sign();判断一个数是正数,负数,零
Math.sign(66);//1,正数
Math.sign(-66);//-1,负数
Math.sign(0);//0,零
17、对象方法的扩展
1、Object.is() 判断两个值是否相等
Object.is(66,66);//true
Object.is(66,61);//false
Object.is(NaN,NaN);//true,特殊
2、Object.assign()对象的合并
let Obj1 = {}
let Obj2 = {}
Object.assign(Obj1,Obj2);//对象2会把对象1覆盖,返回合并后的新对象
3、Object.setPrototypeof()设置原型对象;Object.getPrototypeof();获取原型对象
const obj1 = {name:'周米粒'}
const obj2 = {work:'巡山',address:'落魄山'}
Object.setPrototype(obj1,obj2);设置原型对象
输出结果:{name:'周米粒',
__proto__:{
work:'巡山',
address:'落魄山'
}}
Object.getPrototypeof(obj1);//获取原型对象
18、模块化
将一个大的程序文件,拆分成许多小的程序文件,然后将小文件组合起来
1、好处:
01、防止命名冲突
02、代码复用
03、更容易维护
2、模块化规范产品
1、CommonJS => NodeJS Browserify
2、AMD => requireJS
3、CMD => sealJS
3、 ES6模块化语法(在浏览器中无法直接使用,我们需要在引入模块的 <script> 元素上添加type="module" 属性)
1、export (暴露) 用于规定模块的对外接口
2、import (引入) 用于输入其他模块提供的功能
例1(Vue):
01、单独暴露,全部引入
export let baseUrl = "192.168.18"
export function fun(a,b){return a+b}
使用的地方:
import * as temp form "js文件路径"
console.log(temp)
02、统一暴露,解构赋值形式引入
let baseUrl = "192.168.18"
function fun(a,b){return a+b}
export {baseUrl,fun}
使用的地方:
import {baseUrl,fun} form "js文件路径"
console.log(temp)
03、默认暴露
export default {
fun:function(){}
baseUrl:'192.168.2'
}
使用的地方:
import {default as temp} form "js文件路径"
console.log(temp)
注意:
1、引入 export default 导出的模块不用加 {},引入非 export default 导出的模块需要加 {}
2、一个文件只能导出一个 default 模块。
3、import/export 不能对引入模块重新赋值/定义
4、import/export 只能在模块顶层使用,不能在函数、判断语句等代码块之中引用
(https://zhuanlan.zhihu.com/p/121770261以及尚硅谷视频)
19、ES7
两个方法:
1、includes() 判断数组中是否含有某个元素,返回Boolean值
例:
const arr = ['白也','白玄','白景']
console.log(arr.includes('暖树'));//false
和indexOf类似,不过返回值不一样
2、** 计算一个数的多少次幂
例:
console.log(2 ** 10);//1024
等同于 Math.pow(2,10)
20、ES8--async
- async await 相结合可以让异步代码像同步代码一样;
- 解决异步编程的方式目前有 生成器函数,Promise;async await;
- async函数的返回值为Promise对象
- Promise对象的结果由async函数执行的返回值决定
1、async
使用:
async fun(){
//async返回值是一个Promise对象
//如果返回的结果不是一个Promise类型的对象,返回的结果就是成功的Promise
return 'Srtring';
//抛出错误,返回的结果是一个失败的Promise
throw new Error('错误抛出')
//如果返回值是一个Promise对象(多数情况下)
return new Promise((resove,reject)=>{
resove('成功的数据');//返回结果则为成功
reject('失败的数据');//但会结果则为失败
})
};//函数那面加一个async
fun().then(()=>{
//resole('成功的数据')在这里会被得到
},()=>{
//reject('失败的数据')在这里会被得到
})
21、ES8--async await
await表达式:
- await必须写在async函数中(但是async函数里面不一定要有await)
- await右侧的表达式一般为Promise对象
- await返回的是Promise成功的值
- await的Promise失败了,就会抛出异常,需要通过try...catch捕获处理
结合使用
function fun1(){
return new Promise((resove,reject)=>{
//getData定义的一个请求数据的函数
getData(){
if(res.message=='success'){
resove(res)
}else{
reject(res.message)
}
}
})
}
async tempFun(){
let res = await fun1()
//res就是请求数据的函数返回的值
}
22、ES8--对象方法的拓展
示例:
const tempObj = {
name:'米粒',
size:'small',
address:['哑巴湖','落魄山']
}
1、获取对象的所有键
Object.keys(tempObj);//['name','size','address']
2、获取对象所有的值
Object.values(tempObj);//['米粒','small',['哑巴湖','落魄山']]
3、将对象以数组的形式返回,数组的第一个值是键,第二个值是内容
let temp = Object.entries(tempObj);//[['name','米粒'],[...],[...]]
使用entries()方法可以方便创建一个map,例:
const m = new Map(temp);
{
{'name'=>'米粒'},
{'size'=>'small'},
{'address'=>['哑巴湖','落魄山']}
}
4、获取对象属性的描述对象
Object.getOwnPropertyDescriptors(tempObj)
23、ES9--扩展运算符与rest参数
- rest参数和扩展运算符在ES6中已经引入,不过ES6中只针对于数组,在ES9中为对象提供了像数组一样的rest参数和扩展运算符
function fun({p1,p2,...pn}){
console.log(p1,p2,pn);//'暖树','景清',{p3:'米粒',p4:'裴钱',p5:'大白鹅'}
}
fun({p1:'暖树',p2:'景清',p3:'米粒',p4:'裴钱',p5:'大白鹅'})
例2:
const obj1 = {a:'洛阳',b:'轩辕青峰'}
const obj2 = {a:'大秦帝',b:'轩辕敬诚'}
console.log({...obj1,...obj2});//{a:'洛阳',b:'轩辕青峰',a:'大秦帝',b:'轩辕敬诚'}
24、ES9--正则扩展:命名捕获分组
例(原来的):
let str = '<a href = "https://www.baidu.com">百度</a>'
需求:提取URL和文本
const reg = /<a href = "(.*)">(.*)</a>/
console.log(reg.exec(str));
返回值为一个数组,
1、第一个值是全部的内容:'<a href = "https://www.baidu.com">百度</a>'
2、第二个值是第一个匹配到的结果:"https://www.baidu.com"
3、第三个值为第二个匹配到的结果:"百度"
4、groups为 undefined
例(现在的):
let str = '<a href = "https://www.baidu.com">百度</a>'
需求:提取URL和文本
const reg = /<a href = "(?<url>.*)">(?<text>.*)</a>/
console.log(reg.exec(str));
返回的其他的都一样,只有groups不同:
groups:
text:"百度",
url:"https://www.baidu.com"
25、ES9--正则扩展:反向断言
26、ES9--正则扩展:dotAll模式
27、ES10--对象的扩展方法
Object.fromEntries()
创建一个二维数组
const arr= [['落魄山','长命','周肥'],['绸缪山','米裕','崔嵬']];
console.log(Object.fromEntries(arr));
结果:{'落魄山':'长命,周肥','绸缪山':'米裕,崔嵬'}
相当于把二维数组转化为对象
ES8的Object.entries()把对象转化为二维数组,例:
console.log(Object.entries({'落魄山':['周肥','长命']}))
结果:[['落魄山',['周肥','长命']]]
28、ES10的字符串扩展方法
- str.trimStart()清除字符串左侧空白
- str.trimEnd()清除字符串右侧空白
let str = ' 红豆 '
str.trimStart()
str.trimEnd()
然后 str.trim()是清除字符转两端的空格
29、ES10--数组的扩展方法
- arr.flat(number)将多维数组转化为低维数组,参数是一个数组,代表深度,例:
const arr = [1,2,3,[,4,5,6]]
console.log(arr.flat());//[1,2,3,4,5,6]
const arr2 = [1,2,3,[4,5,[6,7]]]
consolog.log(arr2.flat(2));//[1,2,3,4,5,6,7]
const arr5 =[1,[2,[3,[4,[5,[6]]]]]]
console.log(arr5.flat(5));//[1,2,3,4,5,6]
- arr.flatMap()
const arr = [1,2,3]
const arr1 = arr.map(item=>item*10)
console.log(arr1);//[[10],[20],[30]]
const arr2 = arr.flatMap(item=>item*10)
console.log(arr2);//[10,20,30]
30、ES10--Symbol的扩展
- Symbol.prototype.description 用于获取Symbol的字符串描述
let temp = Symbol('周米粒')
console.log(temp.description);//周米粒
31、ES11--私有属性
例子:
class person {
name:'余斗';
#age:8000;//私有属性加#
constructor(name,age){
this.name = name;
this.#age = age
}
}
let man = new person('余斗',8000)
console.log(man ); //{name:'余斗',#age:8000}
单独某个:
console.log(man.name);//余斗
console.log(man.#age);//报错
获取私有属性方式:
class person {
name:'余斗';
#age:8000;//私有属性加#
constructor(name,age){
this.name = name;
this.#age = age
}
intro(){
console.log(this.#age);//8000
}
}
32、ES11--Promise.allSettled
- Promise.addSettled(Promise数组),接收的是一个Promise数组,返回的结果是永远是成功的状态,成功的值是每一个Promise的状态和结果。
const p1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve('成功的返回01')
},1500)
})
const p2 = new Promise((resolve,reject)=>{
setTimeout(()=>{
//resolve('成功的返回02')
reject('失败的返回02')
},1500)
})
const res = Promise.allSettled;
结果永远是成功的,哪怕有Promise是失败的,但是总的永远是成功的。
类似的有:
Promise.all()
接收一个Promise数组,返回结果根据Promise的状态决定,全部成功则为成功,有一个失败则为失败。
33、ES11-String.prototype.matchAll
- 用于得到正则批量匹配的结果
let str = `
<ul>
<li>
<a>霸王别姬</a>
<p>上映时间:不晓得</p>
</li>
<li>
<a>老酒馆</a>
<p>上映时间:不晓得</p>
</li>
</ul>
`
声明正则:
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/sg
const res = str.matchAll(reg)
for(let v of res){
console.log(v)
}
34、ES11--可选链操作符
const params = {
url:{
baseUrl:'192.168.0.107',
name:'locahost'
}
}
function fun1(params){
const temp = params.url.baseUrl;
console.log(temp)
}
fun1(params);//192.168.0.107
fun1();//报错
想要不报错:
function fun1(params){
const temp = params&¶ms.url&¶ms.url.baseUrl;
console.log(temp)
}
fun1(params);//192.168.0.107
fun1();//undefined
//可选链操作符
function fun2(params){
const temp = params?.url?.baseUrl;
console.log(temp)
}
fun(params);//192.168.0.107
fun();//undefined
35、ES11--动态import
36、ES11--bigint
let num = 66n
console.log(num,typeof(num));//66n bigint
整数转化为bingint类型
console.log(BigInt(66));//66n
小数
console.log(BigInt(66.6));//报错
主要运用于大数值的运算
let max = Number.MAX_SAFE_INTEGER
console.log(max);9007099254740991
console.log(max+1);9007099254740992
console.log(max+2);9007099254740992
console.log(BigInt(max));9007099254740991n
console.log(BigInt(max)+1);//报错
console.log(BigInt(max)+BigInt(1));9007099254740992n
console.log(BigInt(max)+BigInt(2));9007099254740993n
37、ES11--globalThis
无视环境直接使用全局对象。
网友评论