ES6(ECMAScript 2015)及以上版本引入了许多新特性,每个版本都有不同的增强和改进。以下是 ES6 及以上版本的新特性的详细描述:
ES6(ECMAScript 2015):
-
let 和 const 声明:引入块级作用域的变量声明,用于替代 var 声明,解决了变量提升的问题。
-
箭头函数:用 “=>” 符号定义函数,自动绑定父级上下文的 this,并且没有自己的 this。
-
模板字符串:使用反引号(`)定义多行字符串和字符串插值,可以在字符串中插入变量。
-
解构赋值:从数组或对象中提取值,赋值给变量,方便处理数据。
-
默认参数值:在函数定义中为参数设置默认值,简化函数的调用。
-
扩展运算符:用三个点(…)表示,用于将数组或对象展开成多个参数或元素。
-
类和继承:引入 class 和 extends 关键字,实现了更加面向对象的编程。
-
Promise:用于处理异步操作的对象,解决了回调地狱的问题,提供了更加优雅的异步编程方式。
-
Set 和 Map 数据结构:Set 是一种无重复值的集合,Map 是键值对的集合,提供了更多方便的数据结构。
-
Symbol:引入了一种新的原始数据类型 Symbol,用于创建唯一的标识符。
ES7(ECMAScript 2016):
-
Array.prototype.includes:新增了数组的 includes 方法,用于判断数组中是否包含指定的值。
-
指数操作符:引入了指数操作符(**),用于计算指数。
ES8(ECMAScript 2017):
-
async/await:引入了 async 和 await 关键字,用于简化异步编程,使异步代码看起来像同步代码一样。
-
Object.values 和 Object.entries:新增了 Object.values 和 Object.entries 方法,分别用于获取对象的值和键值对。
-
String padding:String.prototype.padStart、String.prototype.padEnd
-
函数参数列表结尾允许逗号:方便使用git进行多人协作开发时修改同一个函数减少不必要的行变更。
-
Object.getOwnPropertyDescriptors():用来获取一个对象的所有自身属性的描述符,如果没有任何自身属性,则返回空对象。
const obj = {
name: 'lxm',
get age() { return '28' }
};
Object.getOwnPropertyDescriptors(obj)
-
SharedArrayBuffer 对象:用来表示一个通用的,固定长度的原始二进制数据缓冲区
-
Atomics 对象:提供了一组静态方法用来对 SharedArrayBuffer 对象进行原子操作
ES9(ECMAScript 2018):
- 异步迭代器:引入了异步迭代器和 for-await-of 循环,用于异步迭代数据。
//before
async function process(array) {
for (let i of array) {
await doSomething(i);
}
}
async function process(array) {
array.forEach(async i => {
await doSomething(i);
});
}
//after ES9
async function process(array) {
for await (let i of array) {
doSomething(i);
}
}
-
Promise.finally():无论Promise运行成功还是失败,运行相同的代码,例如清除,删除对话,关闭数据库连接等。
promise.then().catch().finally(()=>console.log("finish here!"));
-
Rest/Spread 属性:引入了对象的 Rest 和 Spread 属性,即Rest参数和扩展运算符,用于简化对象的操作。
-
正则表达式命名捕获组
const reDate = /([0-9]{4})-([0-9]{2})-([0-9]{2})/,
match = reDate.exec('2018-04-30'),
year = match[1], // 2018
month = match[2], // 04
day = match[3]; // 30
//使用符号?<name>,任何匹配失败的命名组都将返回undefined。
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
-
正则表达式反向断言(lookbehind)
-
正则表达式dotAll模式
正则表达式中点.匹配除回车外的任何单字符,标记s改变这种行为,允许行终止符的出现,例如:/hello.world/.test('hello\nworld'); // false
/hello.world/s.test('hello\nworld'); // true
ES10(ECMAScript 2019):
-
Array.prototype.flat 和 Array.prototype.flatMap:新增了数组的 flat 和 flatMap 方法,用于扁平化和映射数组。
-
String.prototype.trimStart 和 String.prototype.trimEnd:新增了字符串的 trimStart 和 trimEnd 方法,用于去除字符串的开头和结尾空格。
-
String.prototype.matchAll:为所有匹配的匹配对象返回一个迭代器
-
Symbol.prototype.description:只读属性,回 Symbol 对象的可选描述的字符串。
typeof a.description === "string"
-
Object.fromEntries():返回一个给定对象自身可枚举属性的键值对数组
-
可选 Catch参数:从
try{}catch(e){}
变为try{}catch{}
-
JSON Superset 超集:主要解决了JSON字符串中包含有行分隔符 (\u2028) 和段落分隔符 (\u2029) 的问题,这些字符在之前的ECMAScript中会导致解析错误。
JSON.parse('"\u2028"');
//“” -
JSON.stringify() 加强格式转化,使其能够正确处理一些超出范围的Unicode字符。
-
Array.prototype.sort() 更加稳定
-
Function.prototype.toString() 重新修订:之前,Function.prototype.toString()只会返回了函数的主体,但没有注释和空格。现在,函数返回的结果与编写的一致:
//函数定义
function /* a comment */ foo() {}
//ES10之前
foo.toString(); // 'function foo() {}'
//ES10之后
foo.toString(); // 'function /* a comment */ foo () {}'
ES11(ECMAScript 2020):
-
可选链操作符:引入了可选链操作符(?.),用于简化链式属性访问,防止出现未定义的错误。
-
空位合并操作符:引入了空位合并操作符(??),用于提供默认值,当值为 null 或 undefined 时使用默认值。
-
动态 import ():
import('a').then(module => { console.info(module) });
-
BigInt:有两种使用方式:(1)在数字字面量的后面添加后缀n;(2)使用其构造函数BigInt。
支持位运算符(不支持无符号位移)、BigInt 无法直接和 Number运算、一些内置模块如 Math 也不支持 BigInt,如Math.pow(2n, 64n)
、BigInt 和 Number 相等,但并不严格相等、Bigint支持和Number通过符号>
或<
比较大小 -
globalThis:window(Window)、self(Worker)、global(node.js)。
最开始通过const globals = (new Function('return this;'))()
拿到全局对象,但 Chrome APP 内容安全策略不允许。
es6-shim穷举所有可能的全局属性:var getGlobal = function () { if (typeof self !== 'undefined') { return self; } if (typeof window !== 'undefined') { return window; } if (typeof global !== 'undefined') { return global; } throw new Error('unable to locate global object'); }; var globals = getGlobal(); if (!globals.Reflect) { defineProperty(globals, 'Reflect', {}, true); }
-
Promise.allSettled:新增了 Promise.allSettled 方法,用于处理多个 Promise 对象,返回所有 Promise 的状态。
-
for in 结构:用于规范for-in语句的遍历顺序。
ES12(ECMAScript 2021):
-
String.prototype.replaceAll:新增了字符串的 replaceAll 方法,用于替换所有匹配的子字符串。
-
Promise.any:新增了 Promise.any 方法,用于处理多个 Promise 对象,只要有一个完成即可。
-
逻辑赋值操作符 ??=、&&=、 ||=,有了这个新的标准中,逻辑表达式的操作符(&&、||、??)也可以简写了!
-
WeakRef创建一个对象的弱引用,而不会阻止该对象被垃圾回收器回收。用构造函数来创建一个WeakRef对象
ref = new WeakRef(data);
用WeakRef.prototype.deref()来取到原对象的值。obj = ref.deref();
-
下划线分隔符:数字太长会导致可读性很差。使用了数字分隔符 _ (下划线),就可以让数字读的更清晰。
let num = 2_3333_3333
和let num = 233333333
等价 -
Intl.ListFormat:是一个构造函数,处理和多语言相关的对象格式化操作:
//参数属性 style:long|short; type:conjunction|disjunction
const list = ['Apple', 'Orange', 'Banana']// 会根据语言来返回相应的格式化操作
// "Apple, Orange and Banana"
new Intl.ListFormat('en-GB', { style: 'long', type: 'conjunction' }).format(list);
// "Apple、Orange或Banana"
new Intl.ListFormat('zh-cn', { style: 'short', type: 'disjunction' }).format(list);
- Intl.DateTimeFormat API 中的 dateStyle 和 timeStyle 的配置项
(1) dateStyle 用于指定日期的显示样式,可以设置为以下值:full | long | medium | short
(2) timeStyle 用于指定时间的显示样式,可以设置为以下值:full | long | medium | short
ES13(ECMAScript 2022):
- Array.prototype.at:新增了数组的 at 方法,用于根据索引获取元素,支持负数索引。
以上是 ES6 及以上版本的主要新特性,每个版本都为 JavaScript 提供了更多的功能和语法糖,使得开发更加便捷和高效。随着 ECMAScript 的不断演进,未来的版本还会引入更多的新特性和改进,使得 JavaScript 成为更加强大和灵活的语言。