相关文章
新特性
一、ES7(ECMAScript 2016)
指数运算符(Exponentiation Operator)
使用双星号 ** 表示乘方运算符,用于计算一个数的幂次方。
1
| let result = 2 ** 3; // 8
|
Array.prototype.includes() 方法
includes() 方法用于判断数组是否包含某个指定的值,返回布尔值。
1 2 3
| let array = [1, 2, 3, 4, 5]; let hasThree = array.includes(3); // true let hasTen = array.includes(10); // false
|
二、ES8(ECMAScript 2017)
Object.values() 和 Object.entries() 方法
Object.values() 方法返回一个给定对象自身的所有可枚举属性值的数组。
Object.entries() 方法返回一个给定对象自身可枚举属性的 [key, value] 数组。
1 2 3
| const obj = { foo: 'bar', baz: 42 }; console.log(Object.values(obj)); // ['bar', 42] console.log(Object.entries(obj)); // [['foo', 'bar'], ['baz', 42]]
|
Async 函数(异步函数)
Async 函数是用来声明一个异步函数,使得函数内部可以使用 await 关键字来等待 Promise 对象的状态改变。
1 2 3 4 5
| async function fetchData() { let response = await fetch('https://api.example.com/data'); let data = await response.json(); return data; }
|
String.prototype.padStart() 和 String.prototype.padEnd() 方法
padStart() 方法用于将当前字符串用指定字符串填充,使得结果字符串达到指定的长度。填充从当前字符串的开始(左侧)进行。
padEnd() 方法用于将当前字符串用指定字符串填充,使得结果字符串达到指定的长度。填充从当前字符串的末尾(右侧)进行。
1 2 3
| let str = '123'; console.log(str.padStart(5, '0')); console.log(str.padEnd(5, '0'));
|
Object.getOwnPropertyDescriptors() 方法
getOwnPropertyDescriptors() 方法返回指定对象所有自身属性(非继承属性)的描述符。
1 2 3 4 5 6 7 8 9 10
| const obj = { foo: 123, bar: 'abc' }; console.log(Object.getOwnPropertyDescriptors(obj)); /* { foo: { value: 123, writable: true, enumerable: true, configurable: true }, bar: { value: 'abc', writable: true, enumerable: true, configurable: true } } */
|
三、ES9(ECMAScript 2018)
异步迭代(Async Iteration)
异步迭代允许在异步可迭代对象上使用 for-await-of 循环,以便处理异步生成的数据。
1 2 3 4 5 6 7 8 9 10 11
| async function fetchItems() { let response = await fetch('https://api.example.com/items'); let data = await response.json(); return data; }
async function processItems() { for await (let item of fetchItems()) { console.log(item); } }
|
Rest/Spread 属性(Rest/Spread Properties)
Rest/Spread 属性允许对象使用 … 语法来扩展和收集属性。
1 2 3 4
| let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 }; console.log(x); console.log(y); console.log(z);
|
Promise.finally() 方法
finally() 方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。
1 2 3 4 5
| fetch('https://api.example.com/data') .then(response => response.json()) .then(data => console.log(data)) .catch(error => console.error(error)) .finally(() => console.log('Promise settled'));
|
四、ES10(ECMAScript 2019)
空值合并运算符(Nullish Coalescing Operator)
空值合并运算符 ?? 用于判断一个值是否为 null 或 undefined,如果是,则返回默认值,否则返回该值本身。
1 2
| let value1 = null ?? 'default'; // 'default' let value2 = 'hello' ?? 'default'; // 'hello'
|
String.prototype.trimStart() 和 String.prototype.trimEnd() 方法
trimStart() 方法用于去除字符串开头的空白字符。
trimEnd() 方法用于去除字符串末尾的空白字符。
1 2 3
| let str = ' hello '; console.log(str.trimStart()); console.log(str.trimEnd());
|
Array.prototype.flat() 和 Array.prototype.flatMap() 方法
flat() 方法用于将嵌套数组展平为指定层数的数组。
flatMap() 方法首先使用映射函数映射每个元素,然后将结果压缩成一个新数组。
1 2 3 4 5 6
| let arr = [1, [2, 3], [4, [5, 6]]]; console.log(arr.flat()); console.log(arr.flat(2));
let arr2 = [1, 2, 3]; console.log(arr2.flatMap(x => [x * 2]));
|
五、ES11(ECMAScript 2020)
可选链操作符(Optional Chaining)
可选链操作符 ?. 可以简化访问深层嵌套对象属性时的代码,避免因为中间属性为 null 或 undefined 而导致的错误。
1 2 3 4 5 6 7 8
| let obj = { foo: { bar: { baz: 42 } } }; let value = obj.foo?.bar?.baz;
|
空值合并运算符(Nullish Coalescing Operator)的链式调用
在 ES11 中,空值合并运算符 ?? 也可以进行链式调用,以简化多个可能为 null 或 undefined 的值的处理。
1
| let value = null ?? undefined ?? 'default'; // 'default'
|
BigInt 数据类型
BigInt 是一种新的原始数据类型,用于表示任意大的整数。在数字末尾添加 n 表示一个 BigInt 类型的字面量。
1
| const bigIntValue = 1234567890123456789012345678901234567890n
|
全局对象 globalThis
在 ES11 中引入了一个全局对象 globalThis,它始终指向全局环境(无论是浏览器环境还是 Node.js 环境),以解决不同 JavaScript 环境下全局对象的访问问题。
1 2
| console.log(globalThis === window) console.log(globalThis === global)
|
动态导入 import()
可以根据运行时的条件动态选择要导入的模块。
1 2 3 4 5
| const moduleName = condition ? './module1.js' : './module2.js'; import(moduleName) .then(module => { });
|
六、ES12(ECMAScript 2021)
Promise.any() 方法
Promise.any() 方法用于将多个 Promise 对象包装成一个新的 Promise 对象,只要其中一个 Promise 对象状态变为 fulfilled,就会立即返回该 Promise 的值。
1 2 3 4 5 6 7
| Promise.any([ fetch('https://api.example.com/data1'), fetch('https://api.example.com/data2'), fetch('https://api.example.com/data3') ]) .then(response => console.log(response)) .catch(error => console.error(error));
|
Numeric Separators 数字分隔符
可以在数字中使用下划线 _ 来分隔数字,以提高数字的可读性。
1 2
| let bigNumber = 1_000_000_000 console.log(bigNumber)
|
Promise.allSettled() 方法
Promise.allSettled() 方法用于将多个 Promise 对象包装成一个新的 Promise 对象,该 Promise 对象在所有 Promise 都已经完成(无论是 fulfilled 还是 rejected)后才会变为 fulfilled 状态,返回一个包含每个 Promise 结果的对象数组。
1 2 3 4 5 6
| Promise.allSettled([ Promise.resolve('resolved'), Promise.reject('rejected') ]) .then(results => console.log(results)) .catch(error => console.error(error));
|
七、ES13(ECMAScript 2022)
声明类的字段
到目前为止,在ES规范中,类的字段定义和初始化是在类的构造函数中完成的。但是在新的提案中,类字段可以在类的顶层被定义和初始化
1 2 3 4 5
| class Point { name title size = 1 }
|
私有方法&字段
用#前缀来定义类的私有方法和字段。
1 2 3 4 5 6 7 8 9 10 11
| class Person { name; #age; get #age(){ return #age; } $initValue(){ this.name = ''; this.#age = 12; } }
|
类的静态公共方法和字段
在之前的类的字段和私有方法提案的基础上,为JavaScript类增加了静态公共字段、静态私有方法和静态私有字段的特性。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Enum { static collectStaticFields() { this.enumKeys = Object.keys(this); } } class ColorEnum extends Enum { static red = Symbol('red'); static green = Symbol('green'); static blue = Symbol('blue'); static _ = this.collectStaticFields();
static logColors() { for (const enumKey of this.enumKeys) { console.log(enumKey); } } } ColorEnum.logColors();
|
ECMScript 类静态初始化块
类静态块提议提供了一种优雅的方式,在类声明/定义期间评估静态初始化代码块,可以访问类的私有字段
1 2 3 4 5 6 7 8 9
| class Person { static name age } try { Person.name = getNameA() } catch { Person.name = getNameB() }
|
Object.hasOwn(object, property)
简单讲就是使用 Object.hasOwn 替代 Object.prototype.hasOwnProperty.call
1 2 3 4
| const person = {name: 'lxm'} console.log(Object.prototype.hasOwnProperty.call(person, 'name'))
console.log(Object.hasOwn(person, 'name'))
|