ES6
ES6中class类的使用
static 类的静态方法
extends 类的继承
super
在构造函数里的this/return之前调用
在子类方法里调用父类方法
在子类里的静态方法里调用
继承自内置类
类的混入mixin(JS中只有单继承)
字面量增强
property shorthand(属性的简写)
method shorthand(方法的简写)
computed propeety name计算属性名[]
解构
数组的解构[]
//对数组的解构 var [item1,item2]=props //解构后面的元素 var [,,itemz]=props //解构部分元素,并将剩余元素放在一个新的数组中 var [itemx,...newProps]=props //解构默认值 var[itema,itemb,itemc,itemd='define']=props
对象的解构{}
//对象的解构{} var {key1,key2}=obj //改名 var {keym:newKey}=obj //默认值 var {keyn="define"}=obj
let/const
let 变量
const 不可更改的变量,引用类型(内存地址)里的东西可以改
let和const不能重复定义var可以
let和const没有作用域提升,但他们并不是在代码执行阶段才会被创建它们都会被创建在包含他们的词法环境被实例化时,只是let/const不可以被访问,直到词法绑定被求值
var声明的变量会在window上添加一个属性,let/const不会给window对象上添加任何属性
将所有变量定义为const,变量需要改变的时候再改为let,尽量不要使用var(bug温床)
let/const 的暂时性死区
块级作用域
ES5中只有全局作用域和函数作用域
const btns=document.getElementByTagName('button') for (var i=0;i<btns.length;i++){ //有问题的代码 btns[i].onclick=function(){ console.log($`第{i}个按钮被点击了`) //这里因为没有块级作用域,所以i始终为全局的4(btns.length) } //解决方案(ES5) (function(n){ btns[i].onclick=function(){ console.log($`第{n}个按钮被点击了`) //立即执行函数,闭包和函数作用域 } })(i) //使用let(某些特定情况还可以用const) }
模板字符串
$
字符串{变量}字符串
标签模板字符串
function f(m,n){
console.log(m,n,'------')
}
const name='tutu'
const age=18
f`Hello${name}Wo${age}rld`
//输出为 ['Hello','Wo','rld'] tutu ------
函数相关
默认参数:
function f(m='define'){}
并且建议将有默认值的参数放在最后ES5中的实现方法
function f(){ var m=arguments.length>0&&arguments[0]!==undefined?arguments[0]:'define' }
length属性:function.length=<函数的参数个数>,有默认值的参数不算在其内,并且其后的所有参数也不算在内
剩余参数(rest parameter):以...作为前缀,会将剩余的所有参数放在该参数,作为一个数组传递进函数
与ES5中arguments的区别:
rest参数仅包含没有形参的参数,而arguments则包含所有参数
arguments对象是一个类数组的对象,它不含许多数组的内置方法
arguments是早期的ECMA规范,rest参数则是ES6中用于取代arguments的
箭头函数:
没有显式原型,不能用new调用
没有绑定this
没有绑定arguments
展开语法(Spread syntax)
对象的展开语法(ES9):
const obj={...object}
进行的是浅拷贝
数值的表示
进制:0b表示二进制(binary),用0o表示八进制(octal),用0x表示十六进制(Hex,hexadecimal)
大数值连接符_(ES12):
const num=1_000_000_000
新增类型
Symbol类型
作为对象里的唯一key,通过描述来辨别(ES10)
不能通过.来获Symbol的value
当使用Symbol来作为Key时,在遍历、Object.keys等情况下是无法获取这些Symbol值
使用Object.getOwnPropertySymbols获取所有Symbol的key,再进行遍历
Symbol.for(key)创建出一样的Symbol,Symbol.keyFor(<symbol>)来返回key
Set类型
类似数组但是元素不能重复
Set的作用
数组去重
arr = [1,2,3,4,1,2,3] const arr1=Array.from(new Set(arr)) const arr2=[...new Set(arr)]
Set常见属性和方法
属性
size:返回Set中元素的个数
方法
add()
delete() 不支持传入index
has()
clear()
forEach()/for ... of ...
WeakSet类型
只能存放对象类型
对对象的引用为弱引用
弱引用:当某个数据只是弱引用时,会被GC销毁
WeakSet不支持遍历
Map类型
存储映射关系,key可以是string/Symbol以外的数据类型
Map常见属性和方法
属性
size:返回Map中元素的个数
方法
set(key,value)
get(key)
has(key)
delete(key)
clear()
forEach()/for ... of ...
WeakMap类型
key只能是对象类型
对对象的引用为弱引用
WeakMap不支持遍历
Proxy类
ES5中采用Object.defineProperty()来实现该操作,但有很大弊端
作用:创建一个代理,来完成监听对象的操作
objProxy=new Proxy(obj,{Trap})
捕获器(Trap)
函数(TRAP)
作用
get(target,key,receiver)
监听获取值
set(target,key,newValue,receiver)
监听设置值
has(target,key)
监听in操作符
deleteProperty(target,key)
监听删除(delete操作符)
getPrototypeOf()
监听获取对象原型
setPrototypeOf()
监听设置对象原型
isExtensible()
监听对象是否能拓展
preventExtensions()
监听阻止对象拓展的过程
getOwnPropertyDescript()
监听获取对象的属性描述符
defineProperty()
监听定义对象的属性
ownKeys()
监听Object.getOwnPropertyNames()和Object.getOwnPropertySymbols()方法
apply(target,thisArg,argArray)
监听函数apply调用【用于监听函数对象】
construct(target,argArray,newTarget)
监听new操作符【用于监听函数对象】
Receiver是代理对象(适合配套Reflect一起使用),作用是改变this避免某些操作绕过代理
Reflect对象
是一个对象而不是类,目的是为了替代Object上的不规范操作
Reflect的方法与Proxy的捕获器一一对应,也是13个
Reflect.construct(target,argArray,newTarget) newTarget:创建出的对象的新类型
Promise类
处理异步问题(规范化)
在ES5的时候采用的是fn(successCallback,FailCallbac){}
function foo(){ //传入的函数被称为executor return new Promise((resolve,reject)=>{ //异步代码 //成功的回调 resolve(<结果的结果>) //失败的回调 reject(<失败的结果>) }) } //main.js const fooPromise=foo() //then方法传入的回调函数会在Promise执行resolve函数的时候调用 //catchthen方法传入的回调函数会在Promise执行reject函数的时候调用 fooPromise.then((res)=>{},(err)=>{})//node环境下 //等价方法 new Promise((resolve,reject)=>{ }).then(res=>{ },err=>{ })
Promise状态一旦确定不可更改(pending,fulfilled,rejected)
Promise嵌套时,外层promise状态由内层promise决定
Promise.resolve()传入一个对象(thenable)且实现了then方法时,会执行该then方法,且将Promise状态交给该then方法
const obj={ then:(resolve,reject)=>{} }
promise的对象方法
then方法:返回一个新的promise对象
返回值为一个普通值时,将作为返回的新Promise对象的resolve值,默认返回undefined
返回值是一个Promise对象时,该Promise对象的状态将会取代原Promise的状态
返回值是一个实现了then方法的对象(thenable)时,会执行该对象的then方法,且将Promise状态交给该then方法
catch方法:返回一个新的promise对象
promise.then((res)=>{}).catch((err)=>{})
//语法糖,但不符合promise a+规范没有上面提到的两种状态转移
finally方法(ES9):返回一个新的promise对象(少见)
最终执行
promise的类方法
Promise.resolve() 相当于生成一个Promise并执行resolve
Promise.reject() 相当于生成一个Promise并执行reject
Promise.all() 传入多个promise以数组的形式,当所有都执行resolve结果时输出结果数组
如果有一个promise rejected,则返回这个rejected
Promise.allSettled() 当所有Promise都有结果时才有结果,结果是包含对象的数组,且每个对象包含对应Promise状态
Promise.race() 只要有一个Promise变为fulfilled状态就then(),当遇到一个rejected就会执行catch()
Promise.any() ES12 至少等待一个fulfilled状态才会then(),当所有都是rejected时会返回一个AggregateError对象,记录所有错误
AggregateError.errors拿到所有reject信息
ES7
Array Includes
ES5中使用Array.indexOf()?==-1,并且不能判断NAN
指数运算符 **
ES8
Object.values()方法
Object.entries()
entries :[[key1:value1],[key2,value2],[key3,value3]...],在数组中是[index,value]
String Padding
string.padStart(length,separator),在首部用分割符填充字符到指定长度
string.padEnd(length,separator),在尾部用分割符填充字符到指定长度
Trailing-Commas 在参数使用时允许尾部多一个逗号
Object.getOwnPropertyDescriptors 获取一个对象的所有属性描述符
Async Function:async、await
//requestData是一个异步函数 //方案一:多次回调【回调地狱】 requestData('tutu').then(res=>{ requestData(res+'aaa').then(res=>{ requestData(res+'bbb').then(res=>{ console.log(res) }) }) }) //方案二:Promise中的then的返回值解决【没有回调地狱,但可读性差】 requestDate('tutu').then(res=>{ return requestData(res+'aaa') }).then(res=>{ return requestData(res+'bbb') }).then(res=>{ console.log(res) }) //方案三:Promise+generator //生成器函数 function* getData(){ const res1=yield requestData('tutu') const res2=yield requestData(res1+'aaa') const res3=yield requestData(res2+'bbb') console.log(res3) } //手动执行 const generator=getDate() generator.next().value.then(res=>{ generator.next(res).value.then(res=>{ generator.next(res) }) }) //自动执行 function execGenerator(genFn){ const generator=genFn() function exec(res){ const result=generator.next(res) if (result.done) return result.value.then(res=>{ exec(res) }) } exec(res) } execGenerator(getData) //第三方包 const co=require('co') co(getData) //async、await(方法三的语法糖) async function getData(){ const res1=await requestData('tutu') const res2=await requestData(res1+'aaa') const res3=await requestData(res2+'bbb') console.log(res3) }
async声明异步函数关键字
await必须在async函数里面,await关键字下面的代码必须等到await后面的promise resolve时才会执行
await下面的代码相当于在await后面跟着Promise的then里面执行的
await后面的Promise如果reject,则将该reject作为整个异步函数的reject,将被该异步函数的catch所捕获
ES9
Async iterators
Object spread operators /
Promise finally
ES10
flat(depth:number)扁平化(降维);flatMap 相当于map+flat
Object.fromEntries()方法
trimStart() trimEnd()方法
Symbol description
Optional catch bingding
ES11
新增BigInt类型(Number.Max_SAFE_INTEGER)
const bigint=900719925474099100n
n不可省略,且操作时需要显式转换再运算Nullish Coalescing Operator空值合并操作符??
在此前使用||,但无法处理false, '', 0
Optional Chaining可选链 ?.
Global this全局 globalThis
for ... in ...标准化 获取的是key
Dynamic Import 动态导入见单独篇幅
Promise.allSettled
import meta见单独篇幅
ES12
FinalizationRegistry类
const finalRegistry=new FinalizationRegistry(()=>{ console.log("注册在finalRegistry的对象被销毁") }) let obj={name:'tutu'} let info= new WeakRef(obj) finalRegistry.register(obj) obj=null setTimeout(()=>{ console.log(info.deref()?.name) },10000)
WeakRef类 弱引用某个对象
通过WeakRef.deref()拿到引用对象
logical assignment operators逻辑赋值运算 ||= 、&&= 、 ??=
Numberic Separator 数字分隔符_
Sting.replaceAll() 字符串替换
Promise any方法
评论区