1、ES6
现在使用的比较多的可能就是ES6了。
(1)变量声明的方式由var变为let和const;
(2)模板字符串可以使用反引号,在模板字符串里面支持换行,并可以在里面使用${}来包裹一个变量或表达式;
(3)解构赋值,可以快速获取数组和对象的值;
const fruit = ['苹果','西瓜','火龙果'];
const [f1,f2,f3] = fruit
const laoli = {
name:'lili',
age:28,
}
const { name ,age } = laoli
(4)扩展运算符(...)可以将数组或对象展开
(5)箭头函数:函数的快捷写法,不需要通过function关键字创建函数,并且可以省略return关键字.但函数体内的this对象指的是定义时所在的对象,而不是使用时所在的对象;
(6)对象的简化赋值:对象赋值时如果属性名和变量名一致可以简写;
const laowang = {
name:'name',
skill:'skill'
}
const laowang = {
name,
skill
}
(7)类的支持:ES6中添加了对类的支持,引入了class关键字。JS本身就是面向对象,ES6中提供的类实际上只是JS原型模式包装。现在有了class,对象的创建,继承更直观,父类方法的调用,实例化,静态方法和构造函数更加形象化;
(8)for...of循环是最新添加到 JavaScript 循环系列中的循环。 它结合了其兄弟循环形式 for 循环和 for...in 循环的优势,可以循环任何可迭代(也就是遵守可迭代协议)类型的数据。默认情况下,包含以下数据类型:String、Array、Map 和 Set,注意不包含 Object 数据类型(即 {})。默认情况下,对象不可迭代。
(9)两种实现异步的新机制,Promise和Generator
2、ES7
(1) Array.prototype.includes()
函数用来判断一个数组是否包含一个指定的值,如果包含则返回 true,否则返回false
(2)求幂运算符(**)
在ES7中引入了指数运算符**,**具有与Math.pow(..)等效的计算结果。
3、ES8
(1)padStart()
padStart() 方法会用第二个参数中指定的填充字符串,在当前字符串的头部不断填充,直到它达到第一个参数中指定的目标长度
(2)padEnd()
padEnd() 方法会用第二个参数中指定的填充字符串,在当前字符串的尾部不断填充,直到它达到第一个参数中指定的目标长度
(3)兼容性
Object.values()方法返回一个给定对象中所有可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同(区别在于for-in循环枚举原型链中的属性)。
(4)Async
async function声明定义了一个异步函数,它返回一个AsyncFunction对象。
(5)Shared memory and atomics
当共享内存时,多个线程可以在内存中读取和写入相同的数据。原子操作确保可预测的值被写入和读取,即在下一个操作开始之前完成本次操作,并且该次操作不会被中断。
4、ES9
(1)引入异步迭代器(asynchronous iterators),这就像常规迭代器,除了next()方法返回一个Promise。因此await可以和for...of循环一起使用,以串行的方式运行异步操作。
(2)Promise.finally()
一个Promise调用链要么成功到达最后一个.then(),要么失败触发.catch()。若是想要promise无论在成功还是失败的情况下都执行一个方法,就可以在finally进行相应的操作。
(3)Rest/Spread
Rest参数语法允许我们将一个布丁数量的参数表示为一个数组
restParam({
A: 10,
B: 20,
C:30,
});
function restParam({ A, ...x }) {
// A = 1
// x = { B:20, C:30 }
}
(4) 正则表达式命名捕获组
允许命名捕获组使用符号?<name>,在打开捕获括号(后立即命名,示例如下:
const reDate = /(?<year>[0-9]{4})-(?<month>[0-9]{2})-(?<day>[0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match.groups.year, // 2018
month = match.groups.month, // 04
day = match.groups.day; // 30 复制代码
(5)正则表达式反向断言
JavaScript在正则表达式中支持先行断言(lookahead)。这意味着匹配会发生,但不会有任何捕获,并且断言没有包含在整个匹配字段中。例如从价格中捕获货币符号:
const reLookahead = /\D(?=\d+)/,
match = reLookahead.exec('$123.89');
console.log( match[0] );
在ES9中引入以相同方式工作但是匹配前面的反向断言(lookbehind),这样我就可以忽略货币符号,单纯的捕获价格的数字:
const reLookbehind = /(?<=\D)\d+/,
match = reLookbehind.exec('$123.89');
console.log( match[0] );
(6)正则表达式dotAll模式
正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现
/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
(7)正则表达式 Unicode 转义
到目前为止,在正则表达式中本地访问 Unicode 字符属性是不被允许的。ES2018添加了 Unicode 属性转义——形式为\p{...}和\P{...},在正则表达式中使用标记 u (unicode) 设置,在\p块儿内,可以以键值对的方式设置需要匹配的属性而非具体内容。
const reGreekSymbol = /\p{Script=Greek}/u;
reGreekSymbol.test('π'); // true
(8)非转义序列的模板字符串
之前,\u开始一个 unicode 转义,\x开始一个十六进制转义,反引号后跟一个数字开始一个八进制转义。这使得创建特定的字符串变得不可能,例如Windows文件路径
C:\uuu\xxx\111。
5、ES10(东西太多,暂不做详解)
(1) 行分隔符(U + 2028)和段分隔符(U + 2029)符号现在允许在字符串文字中,与JSON匹配
(2)JSON.stringify
(3)Array的flat()方法和flatMap()方法
flat()和flatMap()本质上就是是归纳(reduce) 与 合并(concat)的操作。
(4)String的trimStart()方法和trimEnd()方法
分别去除字符串首尾空白字符
(5)Object.fromEntries()
(6) Symbol.prototype.description
(7)String.prototype.matchAll
(8)简化try {} catch {},修改 catch 绑定
6、ES11(东西太多,暂不做详解)
(1)String 的 matchAll 方法
(2)动态导入语句 import()
(3)import.meta
(4)export * as ns from 'module'
(5)Promise.allSettled
(6)新增数据类型: BigInt
(7)顶层对象: globalThis
(8)空值合并运算符: ??
(9)可选链操作符:?.
7、ES12
(1)replaceAll
返回一个全新的字符串,所有符合匹配规则的字符都将被替换掉
(2)Promise.any
Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise
(3)WeakRefs
使用WeakRefs的Class类创建对对象的弱引用(对对象的弱引用是指当该对象应该被GC回收时不会阻止GC的回收行为)
(4)逻辑运算符和赋值表达式
逻辑运算符和赋值表达式,新特性结合了逻辑运算符(&&,||,??)和赋值表达式
(5)数字分隔符
数字分隔符,可以在数字之间创建可视化分隔符,通过_下划线来分割数字,使数字更具可读性