精读《What‘s new in javascript》

1. 引言

本周精读的内容是:Google I/O 19。

2019 年 Google I/O 介绍了一些激动人心的 JS 新特性,这些特性有些已经被主流浏览器实现,并支持 polyfill,有些还在草案阶段。

我们可以看到 JS 语言正变得越来越严谨,不同规范间也逐渐完成了闭环,而且在不断吸纳其他语言的优秀特性,比如 WeakRef,让 JS 在成为使用范围最广编程语言的同时,也越成为编程语言的集大成者,让我们有信心继续跟随 JS 生态,不用被新生的小语种分散精力。

2. 精读

本视频共介绍了 16 个新特性。

private class fields

私有成员修饰符,用于 Class:

class IncreasingCounter {#count = 0;get value() {return this.#count;}increment() {this.#count++;}
}

通过 # 修饰的成员变量或成员函数就成为了私有变量,如果试图在 Class 外部访问,则会抛出异常:

const counter = new IncreasingCounter()
counter.#count
// -> SyntaxError
counter.#count = 42
// -> SyntaxError

虽然 # 这个关键字被吐槽了很多次,但结论已经尘埃落定了,只是个语法形式而已,不用太纠结。

目前仅 Chrome、Nodejs 支持。

Regex matchAll

正则匹配支持了 matchAll API,可以更方便进行正则递归了:

const string = 'Magic hex number: DEADBEEF CAFE'
const regex = /\b\p{ASCII_Hex_Digit}+\b/gu/
for (const match of string.matchAll(regex)) {console.log(match)
}// Output:
// ['DEADBEEF', index: 19, input: 'Magic hex number: DEADBEEF CAFE']
// ['CAFE',     index: 28, input: 'Magic hex number: DEADBEEF CAFE']

相比以前在 while 语句里循环正则匹配,这个 API 真的是相当的便利。And more,还顺带提到了 Named Capture Groups,这个在之前的 精读《正则 ES2018》 中也有提到,具体可以点过去阅读,也可以配合 matchAll 一起使用。

Numeric literals

大数字面量的支持,比如:

1234567890123456789 * 123;
// -> 151851850485185200000

这样计算结果是丢失精度的,但只要在数字末尾加上 n,就可以正确计算大数了:

1234567890123456789n * 123n;
// -> 151851850485185185047n

目前 BigInt 已经被 Chrome、Firefox、Nodejs 支持。

BigInt formatting

为了方便阅读,大数还支持了国际化,可以适配成不同国家的语言表达形式:

const nf = new Intl.NumberFormat("fr");
nf.format(12345678901234567890n);
// -> '12 345 678 901 234 567 890'

记住 Intl 这个内置变量,后面还有不少国际化用途。

同时,为了方便程序员阅读代码,大数还支持带分隔符的书写方式,可以使用 useGrouping 属性配置,默认为 true:

const nf = new Intl.NumberFormat("fr", { useGrouping: true });
nf.format(12345678901234567890n);
// -> '12 345 678 901 234 567 890'

目前已经被 Chrome、Firefox、Nodejs 支持。

flat & flatmap

等价于 lodash flatten 功能:

const array = [1, [2, [3]]];
array.flat();
// -> [1, 2, [3]]

还支持自定义深度,如果支持 Infinity 无限层级:

const array = [1, [2, [3]]];
array.flat(Infinity);
// -> [1, 2, 3]

这样我们就可以配合 .map 使用:

[2, 3, 4].map(duplicate).flat();

因为这个用法太常见,js 内置了 flatMap 函数代替 map,与上面的效果是等价的:

[2, 3, 4].flatMap(duplicate);

目前已经被 Chrome、Firefox、Safari、Nodejs 支持。

fromEntries

fromEntriesObject.fromEntries 的语法,用来将对象转化为数组的描述:

const object = { x: 42, y: 50, abc: 9001 };
const entries = Object.entries(object);
// -> [['x', 42], ['y', 50]]

这样就可以对对象的 key 与 value 进行加工处理,并通过 fromEntries API 重新转回对象:

const object = { x: 42, y: 50, abc: 9001 }
const result = Object.fromEntries(Object.entries(object).filter(([ key, value]) => key.length === 1).map(([ key, value ]) => [ key, value * 2])
)
// -> { x: 84, y: 100 }

不仅如此,还可以将 object 快速转化为 Map:

const map = new Map(Object.entries(object));

目前已经被 Chrome、Firefox、Safari、Nodejs 支持。

Map to Object conversion

fromEntries 建立了 object 与 map 之间的桥梁,我们还可以将 Map 快速转化为 object:

const objectCopy = Object.fromEntries(map);

目前已经被 Chrome、Firefox、Safari、Nodejs 支持。

globalThis

业务代码一般不需要访问全局的 window 变量,但是框架与库一般需要,比如 polyfill。

访问全局的 this 一般会做四个兼容,因为 js 在不同运行环境下,全局 this 的变量名都不一样:

const getGlobalThis = () => {if (typeof self !== "undefined") return self; // web worker 环境if (typeof window !== "undefined") return window; // web 环境if (typeof global !== "undefined") return global; // node 环境if (typeof this !== "undefined") return this; // 独立 js shells 脚本环境throw new Error("Unable to locate global object");
};

因此整治一下规范也合情合理:

globalThis; // 在任何环境,它就是全局的 this

目前已经被 Chrome、Firefox、Safari、Nodejs 支持。

Stable sort

就是稳定排序结果的功能,比如下面的数组:

const doggos = [{ name: "Abby", rating: 12 },{ name: "Bandit", rating: 13 },{ name: "Choco", rating: 14 },{ name: "Daisy", rating: 12 },{ name: "Elmo", rating: 12 },{ name: "Falco", rating: 13 },{ name: "Ghost", rating: 14 }
];doggos.sort((a, b) => b.rating - a.rating);

最终排序结果可能如下:

[{ name: "Choco", rating: 14 },{ name: "Ghost", rating: 14 },{ name: "Bandit", rating: 13 },{ name: "Falco", rating: 13 },{ name: "Abby", rating: 12 },{ name: "Daisy", rating: 12 },{ name: "Elmo", rating: 12 }
];

也可能如下:

[{ name: "Ghost", rating: 14 },{ name: "Choco", rating: 14 },{ name: "Bandit", rating: 13 },{ name: "Falco", rating: 13 },{ name: "Abby", rating: 12 },{ name: "Daisy", rating: 12 },{ name: "Elmo", rating: 12 }
];

注意 chocoGhost 的位置可能会颠倒,这是因为 JS 引擎可能只关注 sort 函数的排序,而在顺序相同时,不会保持原有的排序规则。现在通过 Stable sort 规范,可以确保这个排序结果是稳定的。

目前已经被 Chrome、Firefox、Safari、Nodejs 支持。

Intl.RelativeTimeFormat

Intl.RelativeTimeFormat 可以对时间进行语义化翻译:

const rtf = new Intl.RelativeTimeFormat("en", { numeric: "auto" });rtf.format(-1, "day");
// -> 'yesterday'
rtf.format(0, "day");
// -> 'today'
rtf.format(1, "day");
// -> 'tomorrow'
rtf.format(-1, "week");
// -> 'last week'
rtf.format(0, "week");
// -> 'this week'
rtf.format(1, "week");
// -> 'next week'

不同语言体系下,format 会返回不同的结果,通过控制 RelativeTimeFormat 的第一个参数 en 决定,比如可以切换为 ta-in

Intl.ListFormat

ListFormat 以列表的形式格式化数组:

const lfEnglish = new Intl.ListFormat("en");
lfEnglish.format(["Ada", "Grace"]);
// -> 'Ada and Grace'

可以通过第二个参数指定连接类型:

const lfEnglish = new Intl.ListFormat("en", { type: "disjunction" });
lfEnglish.format(["Ada", "Grace"]);
// -> 'Ada or Grace'

目前已经被 Chrome、Nodejs 支持。

Intl.DateTimeFormat -> formatRange

DateTimeFormat 可以定制日期格式化输出:

const start = new Date(startTimestamp);
// -> 'May 7, 2019'
const end = new Date(endTimestamp);
// -> 'May 9, 2019'
const fmt = new Intl.DateTimeFormat("en", {year: "numeric",month: "long",day: "numeric"
});
const output = `${fmt.format(start)} - ${fmt.format(end)}`;
// -> 'May 7, 2019 - May 9, 2019'

最后一句,也可以通过 formatRange 函数代替:

const output = fmt.formatRange(start, end);
// -> 'May 7 - 9, 2019'

目前已经被 Chrome 支持。

Intl.Locale

定义国际化本地化的相关信息:

const locale = new Intl.Locale("es-419-u-hc-h12", {calendar: "gregory"
});
locale.language;
// -> 'es'
locale.calendar;
// -> 'gregory'
locale.hourCycle;
// -> 'h12'
locale.region;
// -> '419'
locale.toString();
// -> 'es-419-u-ca-gregory-hc-h12'

目前已经被 Chrome、Nodejs 支持。

Top-Level await

支持在根节点生效 await,比如:

const result = await doSomethingAsync();
doSomethingElse();

目前还没有支持。

Promise.allSettled/Promise.any

Promise.allSettled 类似 Promise.allPromise.any 类似 Promise.race,区别是,在 Promise reject 时,allSettled 不会 reject,而是也当作 fulfilled 的信号。

举例来说:

const promises = [fetch("/api-call-1"),fetch("/api-call-2"),fetch("/api-call-3")
];await Promise.allSettled(promises);

即便某个 fetch 失败了,也不会导致 reject 的发生,这样在不在乎是否有项目失败,只要拿到都结束的信号的场景很有用。

对于 Promise.any 则稍有不同:

const promises = [fetch("/api-call-1"),fetch("/api-call-2"),fetch("/api-call-3")
];try {const first = await Promise.any(promises);// Any of ths promises was fulfilled.console.log(first);
} catch (error) {// All of the promises were rejected.
}

只要有子项 fulfilled,就会完成 Promise.any,哪怕第一个 Promise reject 了,而第二个 Promise fulfilled 了,Promise.any 也会 fulfilled,而对于 Promise.race,这种场景会直接 rejected。

如果所有子项都 rejected,那 Promise.any 也只好 rejected 啦。

目前已经被 Chrome、Firefox 支持。

WeakRef

WeakRef 是从 OC 抄过来的弱引用概念。

为了解决这个问题:当对象被引用后,由于引用的存在,导致对象无法被 GC。

所以如果建立了弱引用,那么对象就不会因为存在的这段引用关系而影响 GC 了!

具体用法是:

const obj = {};
const weakObj = new WeakRef(obj);

使用 weakObjobj 没有任何区别,唯一不同时,obj 可能随时被 GC,而一旦被 GC,弱引用拿到的对象可能就变成 undefined,所以要做好错误保护。

3. 总结

JS 这几个特性提升了 JS 语言的成熟性、完整性,而且看到其访问控制能力、规范性、国际化等能力有着重加强,解决的都是 JS 最普遍遇到的痛点问题。

那么,这些 JS 特性中,你最喜欢哪一条呢?想吐槽哪一条呢?欢迎留言。

讨论地址是:精读《What’s new in javascript》 · Issue #159 · dt-fe/weekly

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/687600.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

MySQL导入/导出数据

MySQL导入/导出数据 文章目录 MySQL导入/导出数据一、MySQL 导入数据1、mysql 命令导入2、source 命令导入3、使用 LOAD DATA 导入数据4、使用 mysqlimport 导入数据4.1、mysqlimport的常用选项介绍 二、MySQL 导出数据1、使用 SELECT ... INTO OUTFILE 语句导出数据2、mysqldu…

找座位 - 华为OD统一考试(C卷)

OD统一考试(C卷) 分值: 100分 题解: Java / Python / C 题目描述 在一个大型体育场内举办了一场大型活动,由于疫情防控的需要,要求每位观众的必须间隔至少一个空位才允许落座。 现在给出一排观众座位分布…

Nginx 正向代理、反向代理

文章目录 前言1. 正向代理1.1 概念1.2 逻辑图1.3 使用场景 2. 反向代理2.1 概念2.2 逻辑图2.3 使用场景 前言 正向代理主要是用来解决访问限制问题;反向代理则是提供负载均衡、安全防护等作用 1. 正向代理 1.1 概念 正向代理是一个位于客户端和目标服务器之间的代理…

入门OpenCV:图像阈值处理

基本概念 图像阈值是一种简单、高效的图像分割方法,目的是将图像转换成二值图像。这个过程涉及比较像素值和阈值,根据比较结果来确定每个像素点的状态(前景或背景)。图像阈值在处理二维码、文本识别、物体跟踪等领域中非常有用。…

数据结构第十六天(二叉树层序遍历/广度优先搜索(BFS)/队列使用)

目录 前言 概述 接口 源码 测试函数 运行结果 往期精彩内容 前言 从前的日色变得慢,车,马,邮件都慢,一生,只够爱一个人。 概述 二叉树的层序遍历可以使用广度优先搜索(BFS)来实现。具体步骤如下&…

LiveGBS流媒体平台GB/T28181常见问题-基础配置流媒体服务配置中本地|内网IP外网IP(可选)外网IP收流如何配置

LiveGBS常见问题基础配置流媒体服务配置中本地|内网IP外网IP外网IP收流如何配置? 1、流媒体服务配置2、播放提示none rtp data receive3、多网卡服务器4、收流端口配置5、端口区间可以如何配置6、搭建GB28181视频直播平台 1、流媒体服务配置 LiveGBS中基础配置-》流…

多线程---创建线程

1.概述 多线程是指从软件或者硬件上实现多个线程并发执行的技术。线程是程序中独立运行的程序片段,每个线程都有独立的执行流程,可以在同一时间内执行不同的任务。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提…

反编译调试C#编写的exe软件和dll方法详解

1.首先需要下载软件dnSpy.exe,下载地址:https://github.com/dnSpy/dnSpy/releases/tag/v6.1.8 2.使用方法: 首先打开项目,我们这里可以选择dll,也可以选择exe 这边我们是打开了一个WPF写的客户端软件。 2.打开后我…

不同品牌和种类的电容与电感实测对比(D值、Q值、ESR、X)

最近买了个LCR电桥,就想测一下手头上的各种电容电感的参数,对比一下。 测试设备是中创ET4410,测量的参数有:电容值、电感值、D(损耗角正切值)、Q(品质因数)、ESR(等效串联电阻)、X(电抗,通常表示为感抗XL或容抗XC)。 …

使用 LangChain+大模型,基于文本数据构建知识图谱

大家好!在本篇博客中,我将带领大家学习知识图谱以及如何利用大模型和自己的文本数据构建一个。 喜欢本文记得收藏、关注、点赞。 什么是知识图谱? 知识图谱,也被称为语义图,是一种智能结构,以高效的方式…

【打工日常】使用docker部署Dashdot工具箱

一、Dashdot介绍 dashdot是一个简洁清晰的服务器数据仪表板,基于React实现 ,主要是显示操作系统、进程、存储、内存、网络这五个的数据。 二、本次实践介绍 1. 本次实践简介 本次实践部署环境为个人测试环境 2. 本地环境规划 本次实践环境规划&#xf…

PyCharm 自动缩进代码 (Auto-Indent Lines)

PyCharm 自动缩进代码 [Auto-Indent Lines] 1. Ctrl A2. Code -> Auto-Indent LinesReferences 1. Ctrl A 全选代码。 2. Code -> Auto-Indent Lines 自动缩进快捷键 Ctrl Alt I。 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

JavaScript 对象判断

如何判断一个对象是否是Set、Map、Array、Object 参考链接: https://blog.csdn.net/yunchong_zhao/article/details/115915624 let set new Set() let map new Map() let arr [] let obj {}console.log(Object.prototype.toString.call(obj)); // [object Obje…

使用Apache ECharts同时绘制多个统计图表

目录 1、介绍 2、相关知识 3、代码 4、效果 🍃作者介绍:双非本科大三网络工程专业在读,阿里云专家博主,专注于Java领域学习,擅长web应用开发、数据结构和算法,初步涉猎Python人工智能开发和前端开发。 …

十四、java 异常

文章目录 异常5.1 初识异常5.1.1 NullPointerException5.1.2 NumberFormatException 5.2 异常类5.2.1 Throwable5.2.2 异常类体系5.2.3 自定义异常 5.3 异常处理5.3.1 try/catch匹配5.3.2 重新抛出异常5.3.3 finally5.3.4 try-with-resources5.3.5 throws5.3.6 对比受检和未受检…

第五次作业:LMDeploy 的量化和部署

参考文档:https://github.com/InternLM/tutorial/blob/main/lmdeploy/lmdeploy.md 基础作业: 使用 LMDeploy 以本地对话、网页Gradio、API服务中的一种方式部署 InternLM-Chat-7B 模型,生成 300 字的小故事(需截图) …

Mac golang下载安装以及环境变量配置

下载地址: All releases - The Go Programming Language 1、选择对应的系统版本 2、双击打开安装包,如图进行安装 3、验证安装 go version

【二分查找】18. 四数之和

18. 四数之和 解题思路 外围的四数之和(fourSumTarget 方法): 首先对输入数组nums进行排序,这样可以方便后面进行双指针搜索,同时也有助于去除重复的元组。遍历排序好的数组,固定第一个数nums[i]然后对剩…

交流非线性RCD负载的工作原理

非线性电阻电容电感(RCD)负载是一种常见的电子元件,广泛应用于各种电子设备中。它的主要作用是限制电流的快速变化,保护电路中的其他元件不受过大的电压或电流冲击。 非线性RCD负载的工作原理主要基于其电阻、电容和电感的特性。当…

js-后端返回参数前端动态切换样式

1.js枚举 // 枚举-js //对应的icon显示 EnumUtil.Type { COMMON: 1, BUY: 2, PRODUCE: 3} 2.动态公共样式组件 <!-- 公共组件-显示对应icon --> <template><div v-html"TaskIcon(statues)" class"pro_set_task"></div> </t…