写点什么

令人期待的 JavaScript 新特性

  • 2019-12-27
  • 本文字数:2970 字

    阅读完需:约 10 分钟

令人期待的 JavaScript 新特性

一个 ECMAScript 标准的制作过程,包含了 Stage 0 到 Stage 4 五个阶段,每个阶段提交至下一阶段都需要 TC39 审批通过。本文介绍这些新特性处于 Stage 3 或者 Stage 4 阶段,这意味着应该很快在浏览器和其他引擎中支持这些特性。

一、类的私有变量

最新提案之一是在类中添加私有变量的方法。我们将使用 # 符号表示类的私有变量。这样就不需要使用闭包来隐藏不想暴露给外界的私有变量。


class Counter {  #x = 0;
#increment() { this.#x++; }
onClick() { this.#increment(); }}
const c = new Counter();c.onClick(); // 正常c.#increment(); // 报错
复制代码


通过 # 修饰的成员变量或成员函数就成为了私有变量,如果试图在 Class 外部访问,则会抛出异常。现在,此特性可在最新版本的 Chrome 和 Node.js 中使用。

二、可选链操作符

你可能碰到过这样的情形:当需要访问嵌套在对象内部好几层的属性时,会得到臭名昭著的错误 Cannot read property ‘stop’ of undefined, 然后你就要修改你的代码来处理来处理属性链中每一个可能的 undefined 对象,比如:


let nestedProp = obj && obj.first && obj.first.second;
复制代码


在访问 obj.first.second 之前,obj 和 obj.first 的值要被确认非 null(且不是 undefined)。目的是为了防止错误发生,如果简单直接的访问 obj.first.second 而不对 obj 和 obj.first 进行校验就有可能产生错误。


有了可选链式调用 ,你只要这样写就可以做同样的事情:


let nestedProp = obj?.first?.second;
复制代码


如果 obj 或 obj.first 是 null/undefined,表达式将会短路计算直接返回 undefined。

三、空位合并操作符

我们在开发过程中,经常会遇到这样场景:变量如果是空值,则就使用默认值,我们是这样实现的:


let c = a ? a : b // 方式 1let c = a || b // 方式 2
复制代码


这两种方式有个明显的弊端,它都会覆盖所有的假值,如 (0, ‘’, false),这些值可能是在某些情况下有效的输入。


为了解决这个问题,有人提议创建一个“nullish”合并运算符,用 ?? 表示。有了它,我们仅在第一项为 null 或 undefined 时设置默认值。


let c = a ?? b;// 等价于 let c = a !== undefined && a !== null ? a : b;
复制代码


例如有以下代码:


const x = null;const y = x ?? 500;console.log(y); // 500const n = 0const m = n ?? 9000;console.log(m) // 0
复制代码

四、BigInt

JS 在 Math 上一直很糟糕的原因之一是,无法精确表示大于的数字 2 ^ 53,这使得处理相当大的数字变得非常困难。


1234567890123456789 * 123;// -> 151851850485185200000 // 计算结果丢失精度
复制代码


幸运的是,BigInt(大整数)就是来解决这个问题。你可以在 BigInt 上使用与普通数字相同的运算符,例如 +, -, /, *, % 等等。


创建 BigInt 类型的值也非常简单,只需要在数字后面加上 n 即可。例如,123 变为 123n。也可以使用全局方法 BigInt(value) 转化,入参 value 为数字或数字字符串。


const aNumber = 111;const aBigInt = BigInt(aNumber);aBigInt === 111n // truetypeof aBigInt === 'bigint' // truetypeof 111 // "number"typeof 111n // "bigint"
复制代码


只要在数字末尾加上 n,就可以正确计算大数了:


1234567890123456789n * 123n;// -> 151851850485185185047n
复制代码


不过有一个问题,在大多数操作中,不能将 BigInt 与 Number 混合使用。比较 Number 和 BigInt 是可以的,但是不能把它们相加。


1n < 2// true
1n + 2// Uncaught TypeError: Cannot mix BigInt and other types, use explicit conversions
复制代码


现在,此特性可在最新版本的 Chrome 和 Node.js 中使用。

五、static 字段

它允许类拥有静态字段,类似于大多数 OOP 语言。静态字段可以用来代替枚举,也可以用于私有字段。


class Colors {  // public static 字段  static red = '#ff0000';  static green = '#00ff00';
// private static 字段 static #secretColor = '#f0f0f0';
}
font.color = Colors.red;font.color = Colors.#secretColor; // 出错
复制代码


现在,此特性可在最新版本的 Chrome 和 Node.js 中使用。

六、Top-level await

ES2017(ES8)中的 async/await 特性仅仅允许在 async 函数内使用 await 关键字,新的提案旨在允许 await 关键字在顶层内容中的使用,例如可以简化动态模块加载的过程:


const strings = await import(`/i18n/${navigator.language}`);
复制代码


这个特性在浏览器控制台中调试异步内容(如 fetch)非常有用,而无需将其包装到异步函数中。



另一个使用场景是,可以在以异步方式初始化的 ES 模块的顶层使用它 (比如建立数据库连接)。当导入这样的“异步模块”时,模块系统将等待它被解析,然后再执行依赖它的模块。这种处理异步初始化方式比当前返回一个初始化 promise 并等待它解决来得更容易。一个模块不知道它的依赖是否异步。


// db.mjsexport const connection = await createConnection();// server.mjsimport { connection } from './db.mjs';server.start();
复制代码


在此示例中,在 server.mjs 中完成连接之前不会执行任何操作 db.mjs。


现在,此特性可在最新版本的 Chrome 中使用。

七、WeakRef

一般来说,在 JavaScript 中,对象的引用是强保留的,这意味着只要持有对象的引用,它就不会被垃圾回收。


const ref = { x: 42, y: 51 };// 只要我们访问 ref ```
复制代码


对象(或者任何其他引用指向该对象),这个对象就不会被垃圾回收


目前在 Javascript 中,WeakMap 和 WeakSet 是弱引用对象的唯一方法:将对象作为键添加到 WeakMap 或 WeakSet 中,是不会阻止它被垃圾回收的。


const wm = new WeakMap();{  const ref = {};  const metaData = 'foo';  wm.set(ref, metaData);  wm.get(ref);  // 返回 metaData}// 在这个块范围内,我们已经没有对 ref 对象的引用。// 因此,虽然它是 wm 中的键,我们仍然可以访问,但是它能够被垃圾回收。
const ws = new WeakSet();ws.add(ref);ws.has(ref);// 返回 true

复制代码


JavaScript 的 WeakMap 并不是真正意义上的弱引用:实际上,只要键仍然存活,它就强引用其内容。WeakMap 仅在键被垃圾回收之后,才弱引用它的内容。


WeakRef 是一个更高级的 API,它提供了真正的弱引用,Weakref 实例具有一个方法 deref,该方法返回被引用的原始对象,如果原始对象已被收集,则返回 undefined 对象。


const cache = new Map();const setValue = (key, obj) => {  cache.set(key, new WeakRef(obj));};
const getValue = (key) => { const ref = cache.get(key); if (ref) { return ref.deref(); }};
// this will look for the value in the cache// and recalculate if it's missingconst fibonacciCached = (number) => { const cached = getValue(number); if (cached) return cached; const sum = calculateFibonacci(number); setValue(number, sum); return sum;};
复制代码


总而言之,JavaScript 中对象的引用是强引用,WeakMap 和 WeakSet 可以提供部分的弱引用功能,若想在 JavaScript 中实现真正的弱引用,可以通过配合使用 WeakRef 和终结器(Finalizer)来实现。


现在,此特性可在最新版本的 Chrome 和 Node.js 中使用。


参考文章:


  • 7 Exciting New JavaScript Features You Need to Know

  • New JavaScript Features Coming in ES2020 That You Can Use Now

  • 精读《What’s new in javascript》

  • 【RPU-A】新的 Top-level await 提案

  • 如何实现 JS 真正意义上的弱引用?


本文转载自微信公众号:前端工匠


2019-12-27 16:382314

评论

发布
暂无评论
发现更多内容

ABAP 一组关键字 IS BOUND, IS NOT INITIAL 和 IS ASSIGNED 的用法辨析

汪子熙

指针 应用 SAP abap 8月月更

【8.12-8.19】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

字节一面:HTTPS 一定安全可靠吗?

程序员小毕

Java 程序员 面试 https 校招

四个层次管好设备,为生产保驾护航

PreMaint

预测性维护 设备管理 设备预测性维护

打了15天,如何做到在容器权限上不失一分?

青藤云安全

容器安全 攻防演练

前半个月的行动中,整个圈子都在疯传的“内网King”到底是个啥?

青藤云安全

网络安全 主机安全 攻防演练

如何避免数据湖变成数据沼泽

Kyligence

数据湖 数据管理 智能多维数据库

数字知识库-知识图谱管理系统

金陵老街

Java 数字化 知识图谱 企事业系统

高效完成需求计划的四个关键 | 敏捷开发

LigaAI

Scrum 敏捷开发 Sprint LigaAI spring event

云图说丨初识可信分布式身份服务

华为云开发者联盟

云计算 安全 后端

5分钟,带你看完24岁60W年薪架构师的简历,上面竟然写着精通JVM

收到请回复

Java JVM java面试 简历模板 金九银十

20万字的《Kafka运维实战宝典》PDF现在免费下载了

石臻臻的杂货铺

大数据 kafka

数据中台逼近炒作顶峰之际,Gartner给想建数据中台的一些建议

雨果

数据中台 Gartner

前端监控系列3 | 如何衡量一个站点的性能好坏

字节跳动终端技术

字节跳动 前端 性能监控 火山引擎 站点性能

故障处理 | DM 搭建 MySQL 8.0 同步链路报错:code=26005

TiDB 社区干货传送门

安装 & 部署 TiDB 源码解读

修筑产学研用一体化的通衢,从一场比赛背后瞭望苏州园区人才培养新范式

脑极体

SAP ABAP 和 Java 里的弱引用(WeakReference)和软引用(SoftReference)

汪子熙

Java 引用 SAP abap 8月月更

Web3.0 DAPP项目智能合约系统开发技术详情

开发微hkkf5566

Python图像处理丨基于OpenCV和像素处理的图像灰度化处理

华为云开发者联盟

Python 人工智能 图像

Meta项目功能测试 | 开启PrestoDB和Aria扫描优化

Alluxio

hive presto Alluxio 大数据 开源 8月月更

当内卷风波及代码领域,看Alluxio将会采取怎样的块分配策略

Alluxio

腾讯 存储 Alluxio block 8月月更

开源一夏 | 在 STM32L051 上使用 RT-Thread (三、无线温湿度传感器 之 I2C通讯)

矜辰所致

开源 RT-Thread 8月月更 STM32L051

开源一夏 | 在 STM32L051 上使用 RT-Thread (四、无线温湿度传感器 之 串口通讯)

矜辰所致

开源 RT-Thread 8月月更 STM32L051

优雅,永不过时!SpringBoot中这样编写Controller层代码,那叫一个完美

Java永远的神

Java 程序员 面试 程序人生 springboot

基于RPC接口的业务侧流量回放

转转技术团队

测试工具 流量回放 测试方案

一文带你认知定时消息发布RocketMQ

华为云开发者联盟

云计算 后端

九章云极DataCanvas公司与中国信通院完成可信AI基础软件战略合作

九章云极DataCanvas

人工智能 数据智能 数智化 可信AI

OpenHarmony有氧拳击之设备端开发

OpenHarmony开发者

OpenHarmony

如何在企业数字化团队内部实现数据分析建模成果的结构化整合沉淀

ModelWhale

工作流 数字化转型 数字化 案例分享 提高效率

马拉车算法 (最长回文串 例题 密码截获)

Five

算法 8月月更

7 天能找到 Go 工作吗?学学 Go 数组和指针试试

梦想橡皮擦

Python 爬虫 8月月更

令人期待的 JavaScript 新特性_文化 & 方法_浪里行舟_InfoQ精选文章