JavaScript ES2021 新特性解析

新特性列表

  • String.prototype.replaceAll
  • Promise.any
  • 逻辑运算符和赋值表达式
  • 数值分隔符
  • Intl.ListFormat
  • Intl.DateTimeFormat 的 dateStyle 和 timeStyle 选项

replaceAll

String.prototype.replaceAll

在 JavaScript 中,replace() 方法仅替换字符串中一个模式的第一个实例。如果我们要替换字符串中某个模式的所有匹配项,则唯一的方法是使用全局正则表达式。

提案方法 replaceAll() 返回一个新字符串,其中模式的所有匹配都会被替代项替换。模式可以是字符串或正则表达式,而替换项可以是字符串或针对每次匹配执行的函数。

let str = 'I use linux, I love linux'
str = str.replaceAll('linux', 'windows');console.log(str)/**** Output ****/
// I use windows, I love windows

Promise.any

ES2021 将引入 Promise.any() 方法,只要这个方法命中了 Promise 列表 / 数组中的第一个已解析的 Promise,就会短路并返回一个值(如示例 1a 中所述)。如果所有的 promise 都被拒绝,那么它将抛出一个汇总错误消息(如示例 1b 所示)。

它与 Promise.race() 不同,因为一旦给定的 Promise 之一被解析或拒绝,Promise.any() 方法就会短路。

示例 1a:即使一个 Promise 在一个已解析的 Promise 之前被拒绝,Promise.any() 仍将返回第一个已解析的 Promise。

Promise.any([new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),new Promise((resolve, reject) => setTimeout(resolve, 1000, 'Second')),new Promise((resolve, reject) => setTimeout(resolve, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))/**** Output ****/
// Result: Second

示例 1b:当所有的 Promise 都被拒绝时,将抛出 AggregateError。

Promise.any([new Promise((resolve, reject) => setTimeout(reject, 200, 'Third')),new Promise((resolve, reject) => setTimeout(reject, 1000, 'Second')),new Promise((resolve, reject) => setTimeout(reject, 2000, 'First')),
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(`error of AggregateError: ` , err))/**** Output ****/
// error of AggregateError: ...
Promise.any([Promise.reject('Error 1'),Promise.reject('Error 2'),Promise.reject('Error 3')
])
.then(value => console.log(`Result: ${value}`))
.catch (err => console.log(err))/****  输出  ****/
// AggregateError: All promises were rejected

逻辑运算符和赋值表达式

在 JavaScript 中有许多赋值运算符和逻辑运算符,如以下基本示例:

// Assignment Operator Example
let num = 5
num+=10
console.log(num) // 15
// Logical Operator Example
let num1 = 6
let num2 = 3
console.log(num1 === 6 && num2 === 2) // false
console.log(num1 === 6 || num2 === 2) // true

新的提案让我们将能把逻辑运算符和赋值运算符结合起来。以下是 &&、||和?? 运算符的一些示例:

a ||= b
//等价于
a = a || (a = b)a &&= b
//等价于
a = a && (a = b)a ??= b
//等价于
a = a ?? (a = b)
带有 && 运算符的逻辑赋值运算符

仅当 LHS 值为真时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with && operator
let num1 = 5
let num2 = 10
num1 &&= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 && (num1 = num2)
// 2. if (num1) num1 = num2
带有||的运算符逻辑赋值运算符

仅当 LHS 值为假时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with || operator
let num1
let num2 = 10
num1 ||= num2
console.log(num1) // 10
// Line 5 can also be written as following ways
// 1. num1 || (num1 = num2)
// 2. if (!num1) num1 = num2
带有?? 运算符的逻辑赋值运算符

ES2020 引入了空值合并运算符,其也可以与赋值运算符结合使用。仅当 LHS 为 undefined 或仅为 null 时,才将 RHS 变量值赋给 LHS 变量。

// Logical Assignment Operator with ?? operator
let num1
let num2 = 10
num1 ??= num2
console.log(num1) // 10
num1 = false
num1 ??= num2
console.log(num1) // false
// Line 5 can also be written as following ways
// num1 ?? (num1 = num2)

数值分隔符 _

新引入的数值分隔符使用 _(下划线)字符,在数值组之间提供分隔,使数值读起来更容易。例如:

let number = 100_000
console.log(number)
/**** Output ****/
// 100000

数字分隔符有助于提高各种数字文字的可读性:

// A decimal integer literal with its digits grouped per thousand:
1_000_000_000_000
// A decimal literal with its digits grouped per thousand:
1_000_000.220_720
// A binary integer literal with its bits grouped per octet:
0b01010110_00111000
// A binary integer literal with its bits grouped per nibble:
0b0101_0110_0011_1000
// A hexadecimal integer literal with its digits grouped by byte:
0x40_76_38_6A_73
// A BigInt literal with its digits grouped per thousand:
4_642_473_943_484_686_707n

它们甚至适用于八进制整数文字(尽管 我想不出 其中分隔符为此类文字提供值 的示例)

// A numeric separator in an octal integer literal: ????‍♀️
0o123_456
请注意,JavaScript 还具有不带显式 0o 前缀的八进制文字的旧式语法。例如,017 === 0o17。在严格模式下或模块内不支持此语法,并且在现代代码中不应使用此语法。因此,这些文字不支持数字分隔符。使用 0o17 风格的文字代替。

Intl.ListFormat

ListFormat 对象带有两个参数,它们都是可选的。第一个参数是语言(语言环境),第二个参数是具有两个属性(样式和类型)的选项对象。

new Intl.ListFormat([locales[, options]])

Intl.ListFormat 有一个称为 format() 的方法,该方法接收一个数组作为一个参数,并以特定于语言环境的方式对其进行格式化。

下面给出了一些示例,这些示例结合了不同的语言环境和选项。

const arr = ['Pen', 'Pencil', 'Paper']
let obj = new Intl.ListFormat('en', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr))
/**** Output ****/
// Pen, Pencil, & Paperobj = new Intl.ListFormat('en', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr))
/**** Output ****/
// Pen, Pencil, and Paperobj = new Intl.ListFormat('en', { style: 'narrow', type: 'conjunction' })
console.log(obj.format(arr))
/**** Output ****/
// Pen, Pencil, Paper// Passing in Italy language tag
obj = new Intl.ListFormat('it', { style: 'short', type: 'conjunction' })
console.log(obj.format(arr))
/**** Output ****/
// Pen, Pencil e Paper// Passing in German language tag
obj = new Intl.ListFormat('de', { style: 'long', type: 'conjunction' })
console.log(obj.format(arr))
/**** Output ****/
// Pen, Pencil und Paper
dateStyle 和 timeStyle 选项

Intl.DateTimeFormat 对象是用来启用语言敏感的日期和时间格式的对象构造器。新提案的 dateStyle 和 timeStyle 选项可用于请求给定长度的,特定于语言环境的日期和时间。

下面是不同的选项和语言(区域设置)的一些示例:

// Time only with short format
let o = new Intl.DateTimeFormat('en' , { timeStyle: 'short' })
console.log(o.format(Date.now()))
// 11:27 PM// Time only with medium format
o = new Intl.DateTimeFormat('en' , { timeStyle: 'medium'})
console.log(o.format(Date.now()))
// 11:27:57 PM// Time only with long format
o = new Intl.DateTimeFormat('en' , { timeStyle: 'long' })
console.log(o.format(Date.now()))
// 11:27:57 PM GMT+11// Date only with short format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'short'})
console.log(o.format(Date.now()))
// 10/6/20// Date only with medium format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'medium'})
console.log(o.format(Date.now()))
// Oct 6, 2020// Date only with long format
o = new Intl.DateTimeFormat('en' , { dateStyle: 'long'})
console.log(o.format(Date.now()))
// October 6, 2020

dateStyle 和 timeStyle 选项与不同的语言标记一起使用,如下例所示:

let abc
// English language
abc = new Intl.DateTimeFormat('en' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// October 6, 2020 at 11:40 PM// Italian language
abc = new Intl.DateTimeFormat('it' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6 ottobre 2020 23:40// German language
abc = new Intl.DateTimeFormat('de' , { timeStyle: 'short', dateStyle: 'long'})
console.log(abc.format(Date.now()))
// 6. Oktober 2020 um 23:40

英文原文:https://codeburst.io/exciting-features-of-javascript-es2021-es12-1de8adf6550b

ES2020

1. 类的私有变量

类的主要目的之一是将代码包含到可重用的模块中。 你创建一个在许多不同地方使用的类,你可能不希望它内部的所有内容都是全局可用的。 现在,通过在变量或函数前面添加一个简单的哈希符号,我们可以将它们完全保留为类内部使用。

class Message {// 定义一个私有变量#message = "Howdy"greet() { console.log(this.#message) }
}
const greeting = new Message()
// 通过实例方法调用访问
greeting.greet() // Howdy
// 直接访问类变量
console.log(greeting.#message) // Private name #message is not defined
2.Promise.allSettled

当我们在使用多实例promises的时候,特别是当他们互相依赖的时候,记录每次调试发生的错误是非常有用的,通过使用Promise.allSettled,我们可以创建一个仅仅当全部的promises完成才返回的promise,他将返回一个包含每个promise执行结果的数组。

const p1 = new Promise((res, rej) => setTimeout(res, 1000));
const p2 = new Promise((res, rej) => setTimeout(rej, 1000));
Promise.allSettled([p1, p2]).then(data => console.log(data));
// [
//   Object { status: "fulfilled", value: undefined},
//   Object { status: "rejected", reason: undefined}
// ]
3.空值合并运算符(??)

空值合并运算符(??)是一个逻辑运算符。当左侧操作数为 null 或 undefined 时,其返回右侧的操作数。否则返回左侧的操作数。

与逻辑或(||)操作符不同,逻辑或会在左操作数为 假值 时返回右侧操作数。也就是说,如果你使用 || 来为某些变量设置默认的值时,你可能会遇到意料之外的行为。比如为假值(例如,’'或 0)时。见下面的例子。

const foo = null ?? 'default string';
console.log(foo);
// expected output: "default string"const baz = 0 ?? 42;
console.log(baz);
// expected output: 0
4.可选链式操作符(?.)

与空值合并操作符类似,JavaScript在处理错误值时可能无法按我们希望的方式工作。如果他是未定义的,我们可以返回一个值,但是如果到它的路径是未定义的呢?

通过在点表示法之前添加一个问号,我们可以使值的路径的任何部分成为可选的,这样我们仍然可以与它交互。

如果访问对象上不存在的属性上的属性,使用.操作符会直接报错。

let person = {};
// 如果person对象不包含profile会报错
console.log(person.profile.name ?? "Anonymous"); // person.profile is undefined
// 下面的路径是可选的,如果person对象不包含profile属性直接返回"Anonymous"
console.log(person?.profile?.name ?? "Anonymous");
console.log(person?.profile?.age ?? 18);
5.BigInt

我们不会深入讨论技术细节,但是由于JavaScript处理数字的方式,当您达到足够高的级别时,就会出现一些意料之外的事情。JavaScript能处理的最大数字是2的53次方,我们可以使用Number的MAX_SAFE_INTEGER属性得到这个值。

const max = Number.MAX_SAFE_INTEGER;
console.log(max); // 9007199254740991
// 如果超过了这个范围,事情就会变得有点奇怪……console.log(max + 1); // 9007199254740992
console.log(max + 2); // 9007199254740992
console.log(max + 3); // 9007199254740994
console.log(Math.pow(2, 53) == Math.pow(2, 53) + 1); // true

我们可以使用新的BigInt数据类型来解决这个问题。通过把字母n放在末尾,我们可以开始使用并与大得离谱的数字进行交互。我们无法将标准数字与BigInt数字混合在一起,因此任何数学运算都需要使用BigInt来完成。

const bigNum = 100000000000000000000000000000n;
console.log(bigNum * 2n); // 200000000000000000000000000000n
6.动态引入(Dynamic Import)

如果你有一个工具函数文件,其中一些函数可能很少被使用,将他们完整导入可能只是浪费资源。现在我们可以使用async/await来动态地导入我们需要的依赖项。

这与我们当前Parcel的设置不兼容,因为我们使用的导入只能在Node.js环境中工作。

math.js

const add = (num1, num2) => num1 + num2;
export { add };

index.js

const doMath = async (num1, num2) => {if (num1 && num2) {const math = await import('./math.js');console.log(math.add(5, 10));};
};
doMath(4, 2);

ES2019

1.String.prototype.trimStart() / String.prototype.trimEnd()

在接收用户输入的文本,我们经常会把头尾的空格文本去掉,来规避展示的不受控情况。自ES5来,String.prototype.trim()被用于去除头尾上的空格、换行符等,现在通过trimStart(),trimEnd()来头和尾进行单独控制。trimLeft()、trimRight()是他们的别名。

const string = ' Hello ES2019! ';
string.trimStart();
// 'Hello ES2019! '
string.trimEnd();
// ' Hello ES2019!'

可以大胆想象一下,未来是不是可以通过传入指定字符串参数来对头尾进行删减。

2.Object.fromEntries()

ES8为我们引入了Object.entries把一个对象转为[key, value]键值对的形式,可以运用于像 Map这种结构中。凡事有来有回,Object.fromEntries()用于把键值对还原成对象结构。

const entries = [ ['foo', 'bar'] ];
const object = Object.fromEntries(entries);
// { foo: 'bar' }
3.Array.prototype.flat() / Array.prototype.flatMap()

把数组展平是Array原型给我们带来的新特性,通过传入层级深度参数(默认为1),来为下层数组提升层级。如果想提升所有层级可以写一个比较大的数字甚至是Infinity,当然不推荐这么做。

[1, 2, [3, 4]].flat();
// [ 1, 2, 3, 4 ]
[1, 2, [3, 4, [5, 6]]].flat(2);
// [ 1, 2, 3, 4, 5, 6 ]

Array.prototype.flatMap()它是Array.prototype.map()和Array.prototype.flat()的组合,通过对map调整后的数据尝试展平操作。

[1, 2, [3, 4]].flatMap(v => {if (typeof v === 'number') {return v * 2} else {return v.map(v => v * 2)}
})
// [2, 4, 6, 8]

4.catch 的参数改为可选
在进行try…catch错误处理过程中,如果没有给catch传参数的话,代码就会报错。有时候我们并不关心错误情况,如:

const isValidJSON = json => {try {JSON.parse(json);return true;} catch (unusedError) {// Unused error parameterreturn false;}
};

在新规范中,我们可以省略catch绑定的参数和括号。

const isValidJSON = json => {try {JSON.parse(json);return true;} catch {return false;}
};
5.Symbol.description

Symbol是ES6中引入的基本数据类型,可以用作对象属性的标识符。描述属性是只读的,可用于获取符号对象的描述,更好了解它的作用。

const symbol = Symbol('This is a Symbol');
symbol;
// Symbol(This is a Symbol)
Symbol.description;
// 'This is a Symbol'
6.JSON Superset 超集

之前如果JSON字符串中包含有行分隔符(\u2028)和段落分隔符(\u2029),那么在解析过程中会报错。

JSON.parse('"\u2028"');
// SyntaxError

现在ES2019对它们提供了支持。

JSON.parse('"\u2028"');
// ''
7.JSON.stringify() 加强格式转化

我们看一下熟知的emoji表现:

'												

JavaScript ES2021 新特性解析相关推荐

  1. 最值得期待的 5 个新特性解析JavaScript ES2021

    最值得期待的 5 个新特性解析JavaScript ES2021 [url]https://m.hongxiu.com/so/%E6%96%B0%E7%89%88%E6%9F%A5%E5%B0%94% ...

  2. 【转】Silverlight 3 Beta 新特性解析(7)- Child Window和Shader Effect篇

    前提条件: 阅读本文之前请确认你已经安装了如下软件 Visual Studio 2008 (Express) SP1 Silverlight 3 Tools For Visual Studio Mic ...

  3. python3.8新特性 逻辑表达式_Python3.8正式发布!新特性解析在这里

    Python3.8正式发布!新特性解析在这里 诗书塞外 Python程序员 10月14日,Python 3.8 正式版发布.这也意味着一个Python开发周期的结束,和另一个开发周期的开始.Pytho ...

  4. 资源放送丨《 先睹为快!Oracle 20c新特性解析》PPT视频

    前段时间,墨天轮邀请到了云和恩墨CTO.ACDU核心专家."Oracle百科全书" 杨廷琨 老师分享<先睹为快!Oracle 20c新特性解析>,在这里我们共享一下PP ...

  5. QGIS 3.20 五大新特性解析

    2021年6月18日,经过4个月的开发周期,QGIS发布了最新版(LR)QGIS 3.20,随之一同发布的还有长期稳定版(LTR)QGIS 3.16.8. 相比3.18版为期4天的打包过程,本次打包时 ...

  6. GreenDao3.0新特性解析(配置、注解、加密)

    Greendao3.0release与7月6日发布,其中最主要的三大改变就是:1.换包名 2.实体注解 3.加密支持的优化 本文里面会遇到一些代码示例,就摘了官方文档和demo里的例子了,因为他们的例 ...

  7. JavaScript——ES10新特性

    JavaScript--ES10新特性 一.对象方法扩展 二.字符串扩展方法 三.数组扩展方法 四.Symbol 扩展 一.对象方法扩展 Object.fromEntries() 方法用来创建对象,但 ...

  8. JavaScript ES2021 最值得期待的 5 个新特性解析

    在写本文时,本文提到的新的 JavaScript 提案功能已进入第 4 阶段,并且几乎肯定会包含在 ES2021 中.你已经可以开始在 最新版本的浏览器,Node.js 和 Babel 中使用. 注意 ...

  9. JSPatch近期新特性解析

    JSPatch在社区的推动下不断在优化改善,这篇文章总结下这几个月以来 JSPatch 的一些新特性,以及它们的实现原理. performSelectorInOC JavaScript 语言是单线程的 ...

最新文章

  1. 亲手制作一个《哈利·波特》人物图谱,原来罗恩和赫敏的姻缘从第一部就已注定?...
  2. 介绍如何安装project 2016方法
  3. 手动设计简单的Token验证
  4. java爬虫框架动态_java爬虫框架webmagic
  5. OpenCASCADE:教程概述
  6. 在oracle中使用Trigger
  7. 第一百一十九期:支付宝历年双十一背后的技术揭秘
  8. 基于spring-boot的社区社交微信小程序,适合做脚手架、二次开发
  9. 如何实现多风格选择 样式实时切换?
  10. SPSS 问卷与量表的区别及联系【SPSS 030期】
  11. 倍福--编码器模块的使用
  12. 金蝶K3系统定制国际销售日报表
  13. 工业线阵相机与面阵相机特点分析
  14. 电阻、电感和电容的原理
  15. 【数据结构 课程设计】识别结点(node) 故障和边缘(edge)故障中的网络断层扫描
  16. Servlet小服务程序(Service + Applet)
  17. 如何启动 WordPress 博客 – 简易指南 – 创建博客(2021)
  18. 微信壁纸小程序源码修复图片无法下载-完美运营版本
  19. effective modern cpp
  20. 科大讯飞离线语音命令词识别的使用说明

热门文章

  1. 设计模式之美:Strategy(策略) -未经作者同意的转载
  2. c# int byte转
  3. Chameleon Install3.0变色龙windows安装程序
  4. 在Windows 2003 IIS 6.0中配置PHP的运行环境(图)
  5. 9:38 2009-7-29
  6. PEAR简介:用PEAR来写你的下一个php程序
  7. 深入理解Magento – 第二章 – Magento请求分发与控制器
  8. UIScrollView 滚动视图 (实例)
  9. UIView的一些基本方法 init、loadView、viewDidLoad、viewDidUnload、dealloc
  10. php读取操作大文件