文档章节

ES2019 中的 JavaScript 新特性

红薯
 红薯
发布于 09/29 14:51
字数 1622
阅读 4695
收藏 44

JavaScript 从成立之初就已经走了很长一段路,提供了许多新的功能,这些功能是专门设计来使该语言更加人性化和提升效率。以下是我最近发现的一些有趣的JavaScript 新增内容。其中一些功能已在 Node,Chrome,Firefox 和 Safari 中可用,而其他功能仍处于建议阶段。

Optional chaining (可选链)

Optional chaining 可选链使用 ?. 操作符来表示,Optional Chaining 使我们能检查一个对象上面是否存在某属性。其它一些语言有类似的特性。例如 C# 有 Null Conditional 操作符。而 JavaScript 的 Optional chaining 在需要深度访问嵌套对象属性时就特别有用。

当我们在访问对象的属性前,我们需要用 ?. 操作符来确定该属性是否存在。

首先看看下面代码:

const users = [
  {
   name: "Olagunju Gbolahan",
   occupation: "Software Developer",
   sayName(){
    console.log(`my name is ${this.name}`);
   },
   address: { office: "New York" }
  },
  { name: "Olawaseyi Moses" },
  { name: "Tunde Ednut" }
];

在该数组对象中,第二个对象是 secondUser:

const secondUser = users[1];

我们需要知道该用户的办公室地址,在没有 Optional chaining 之前,我们需要使用一种很低效的方式来验证该属性是否已存在:

const theAddress = secondUser.address && secondUser.address.office;
console.log(theAddress); // undefined

如果我们是一个深度嵌套的对象,那就必须通过 && 操作符来判断每一层的对象是否有效:

但是有了 optional chaining ,代码便可简化如下:

const theAddress = secondUser?.address?.office;
console.log(theAddress); // undefined

我们还可以使用 optional chaining 来确认对象的某个方法是否存在:

const firstUser = users[0];
console.log(firstUser.sayName?.()); // 我的名字是 Olagunju Gbolahan

如果方法名不存在的话,它会简单的返回 undefined :

console.log(firstUser.sayOccupation?.()); // undefined

目前该特性尚未添加到 JavaScript 规范中,目前还处于草案建议阶段

你可以通过 babel-plugin-proposal-optional-chaining 这个插件来实现相同功能。

你也可以阅读 《Optional Chaining 特性进入 Stage 3,TypeScript 跟进 这篇文章来了解更多关于该特性的进展。

Optional catch binding (可选的错误捕获绑定)

当我们事先知道错误将是什么,并且我们不希望冗余未使用的变量时,此功能将派上用场。 

首先看看常规的 try 和 catch 的代码块:

try {
  const parsedJsonData = JSON.parse(obj);
} catch (error) {
  //obj 变量在使用时没有进行定义
  console.log(obj);
}

而通过错误捕获绑定,我们无需提供未使用的变量,特别是当我们已经为 try 块提供默认处理的情况下:

function getName () {
  let name = "Gbolahan Olagunju";
  try {
    name = obj.details.name
  } catch {}
  console.log(name);
}

管道操作符

这是对 JavaScript 的拟议补充之一,目前处于第1阶段。本质上,它有助于使对同一参数的多个函数调用可读。

它通过将表达式的值作为参数传递给函数来实现。

在没有管道运算符的情况下调用以下函数|>

const capitalize = (input) =>  input[0].toUpperCase() + input.substring(1);
const removeSpaces = (input) => input.trim();
const repeat = (input) => `${input}, ${input}`;

const withoutpipe = repeat(capitalize(removeSpaces('    i am gbols    ')));
console.log(withoutpipe); // I am gbols, I am gbols

而通过管道操作符,可读性大幅提升:

const withpipe = '    i am gbols    '
                |> removeSpaces
                |> capitalize
                |> repeat;
console.log(withpipe); // // I am gbols, I am gbols

String.trimStart 和 String.trimEnd

这两个方法在之前被命名为 trimRight 和 trimLeft,但在 ES2019 中将名字修改为 trimStart 和 trimEnd ,表述更加直观:

示例代码:

let message = "     Welcome to LogRocket      ";
message.trimStart(); // "Welcome to LogRocket      "
message.trimEnd(); // "Welcome to LogRocket";

Object.fromEntries

在聊 Object.fromEntries 之前,有必要先看看 Object.entries.

Object.entries 是在 ES2017 规范中引入的,用于将对象转成数组,并可通过数组相关的函数进行访问。

示例代码:

const devs = {
  gbols: 5,
  andrew: 3,
  kelani: 10,
  dafe: 8,
};
const arrOfDevs = Object.entries(devs);
console.log(arrOfDevs);
//[
//  ["gbols", 5]
//  ["andrew", 3]
//  ["kelani", 10]
//  ["dafe", 8]
//]

然后我们可以使用 filter 方法来获取数组中超过 5 年经验的对象:

const expDevs = arrOfDevs.filter(([name, yrsOfExp]) => yrsOfExp > 5);
console.log(expDevs);
//[
//  ["kelani", 10]
//  ["dafe", 8]
//]

那么就会有一个新的问题:没有一个简单的方法将最新的数组重新变成对象。通常我们需要自己编写代码将数组变成对象:

const expDevsObj = {};
for (let [name, yrsOfExp] of expDevs) {
expDevsObj[name] = yrsOfExp;
}
console.log(expDevsObj);
//{
 //dafe: 8
 //kelani: 10
//}

但是现在通过 Object.fromEntries 就可以把这个过程极大简化:

console.log(Object.fromEntries(expDevs));
//{
 //dafe: 8
 //kelani: 10
//}

Flat

很多使用我们需要处理深度嵌套的数组,这个时候将数组展平就特别重要。

先看看如下代码:

const developers = [
  {
    name: 'Gbolahan Olagunju',
    yrsOfExp: 6,
    stacks: ['Javascript', 'NodeJs', ['ReactJs', ['ExpressJs', 'PostgresSql']]]
  },
  {
    name: 'Daniel Show',
    yrsOfExp: 2,
    stacks: ['Ruby', 'Jest', ['Rails', ['JQuery', 'MySql']]]
  },
  {
    name: 'Edafe Emunotor',
    yrsOfExp: 9,
    stacks: ['PHP', 'Lumen', ['Angular', 'NgRx']]
  }
];

const allStacks = developers.map(({stacks}) => stacks);
console.log(allStacks);
// [
// ['Javascript', 'NodeJs', ['ReactJs', ['ExpressJs', 'PostgresSql']]]
// ['Ruby', 'Jest', ['Rails', ['JQuery', 'MySql']]]
// ['PHP', 'Lumen', ['Angular', 'NgRx']]
// ]

allstacks 变量包含深度嵌套的数组,为了将该数组展平,我们可以使用 Array.prototype.flat 方法。

示例代码:

const flatSingle = allStacks.flat();
console.log(flatSingle);
//[
// "JavaScript",
//  "NodeJs",
// ['ReactJs', ['ExpressJs', 'PostgresSql']]]
// "Ruby",
// "Jest",
// ['Rails', ['JQuery', 'MySql']]]
// "PHP",
// "Lumen"
// ["Angular", "NgRx"]
//]

从上面代码可以推断出数组被展平了一层深,这是 array.prototype.flat 的默认参数。

我们可以向flat方法传递一个参数,以确定要展平的程度。

defaults 参数的值为1。为了完全展平数组,我们可以传递一个无穷大的参数。参数 infinity 使数组完全变平,与数组的深度无关。

示例代码:

const completelyFlat = allStacks.flat(Infinity);
console.log(completelyFlat);
//[
// "JavaScript",
// "NodeJs",
// "ReactJs",
// "ExpressJs",
// "PostgresSql",
// "Ruby",
// "Jest",
// "Rails",
// "JQuery",
// "MySql",
// "PHP",
// "Lumen",
// "Angular",
// "NgRx"
//]

FlatMap

FlatMap 相当于将 map 方法和 flat 方法合并起来,并默认使用深度为 1 的新方法。相当于是以更简洁的代码实现两种逻辑的组合。

下面是一个简单使用 map 和 flatMap 的代码:

let arr = ['my name is Gbols', ' ', 'and i am great developer']; 
console.log(arr.map(word => word.split(' ')));
//[
// ["my", "name", "is", "Gbols"],
// ["", ""],
// ["and", "i", "am", "great", "developer"]
//]

console.log(arr.flatMap(word => word.split(' ')));
//[ "my"
//  "name"
//  "is"
//  "Gbols"
//   ""
//   ""
//   "and"
//   "i"
//   "am"
//   "great"
//   "developer"
//]

总结

在这篇文字中,我们详细介绍了一些 JavaScript 最新添加的新特性,这些新的特性通过减少冗长的代码以及提升代码的可读性来增强了开发者的体验。不过还有很多新的特性在本文中没有涉及,欢迎大家补充和分享。

本文翻译自 https://blog.logrocket.com/new-es2019-javascript-features-every-developer-should-be-excited-about/

欢迎关注我的个人公众号 —— 红薯胡说

© 著作权归作者所有

红薯

红薯

粉丝 21893
博文 151
码字总数 73645
作品 8
深圳
产品经理
私信 提问
加载中

评论(14)

二进制艺术
二进制艺术
红薯 开始 写前端了吗?
代码搬运工er
代码搬运工er
为空链,trim这些,c#写了几年了,js加进来简直666
Holt_Vong
Holt_Vong
花里胡哨 666
手握华为赛神仙
手握华为赛神仙
fromEntries是个好东西
W
WindSpeed
好了,这下javascript 不仅像java还像c#和python 牛逼
久永
久永
js是个筐,什么都能往里装。 js只有肉体(实用需求),没有灵魂(语言本身设计思想,设计哲学)。
一个灰
一个灰
那说明你了解js还不够深入
久永
久永
了解不多都知道一大堆了,了解深入还得了?你就了解够深入了?JS的历史你知道?你很了解?知道创造设计JS用了几年?
陌路人_
陌路人_
swift也有这个东西
XtralPlus
XtralPlus
写C#的人觉得这是个 copy
DanoR
DanoR
唉Babel有插件,ESLint不肯跟进呀,真想早点用上可选链。
淘淘我的小宝宝
淘淘我的小宝宝
调下脚本动态语言是一家
小翔
小翔
一直觉得js更像python,而不是java
ECMASCript 2019可能会有哪些特性?

译者按: 又过了1年... 原文:What's New in JavaScript for 2019 译者: Fundebug 为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。 最近这些年,ECMAS...

Fundebug
01/30
0
0
与ECMAScript最新特性同步

➤ TC39工作流程 现在是一年会发布一次ECMA的新版本,如何尽早了解JavaScript的最新动态、提案进度是需要上心的问题。 根据TC39官方日程,每年3月份在TC39委员会上,Stage 4的特性会被确定,...

william_zhou
02/07
0
0
JavaScript 中的表示任意精度的 BigInt

作为前端开发,不知道大家是否被大整数困扰过?JavaScript 对大整型一直没有支持,想要操作大整型数字必须借助第三方库,除了麻烦还可能有打包过大和运行时效率的问题。对比 Java 中,早就有...

HyG
03/13
0
0
Javascript ES2019中的8个新特性

前言 JavaScript 不断改进和添加更多功能。TC39 已经完成并批准了 ES2019 的这 8 个功能,它有 4 个阶段,这些阶段是: Stage 0: Strawman Stage 1: Proposals Stage 2: Drafts Stage 3: Ca...

_Kirito
02/19
0
0
基于 C 实现的 JavaScript 引擎 - QuickJS

QuickJS 是一个轻量且可嵌入的 JavaScript 引擎,它支持 ES2019 规范,包括 ES module、异步生成器以及 proxies。除此之外,还支持可选的数学扩展,例如大整数(BigInt)、大浮点数(BigFloat)和...

匿名
07/12
14.1K
21

没有更多内容

加载失败,请刷新页面

加载更多

解答二进制求和

思路:创建一个新的字符串,用于记录原两个字符串每位相加的结果。 1、因为是从左到右计算,所以要把字符串先进行反转,用reverse()方法。 2、字符串对齐,采用补零的方法。 3、计算的时候...

无名氏的程序员
8分钟前
1
0
JSONUtils

package com.demo.utils;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Tr......

任梁荣
8分钟前
2
1
在jest中配置typescript

测试是报错: Property 'assign' does not exist on type 'ObjectConstructor' NodeJS已经是最新版了,但道理不需要polyfill。 然后发现是typescript的lib没有"es2015.core",说明ts-jest没有......

linsk1998
9分钟前
1
0
Redis实现分布式文件夹锁

缘起 最近做一个项目,类似某度云盘,另外附加定制功能,本人负责云盘相关功能实现,这个项目跟云盘不同的是,以项目为分配权限的单位,同一个项目及子目录所有有权限的用户可以同时操作所有...

逸竹小站
18分钟前
2
0
Andorid SQLite数据库开发基础教程(2)

Andorid SQLite数据库开发基础教程(2) 数据库生成方式 数据库的生成有两种方式,一种是使用数据库管理工具生成的数据库,我们将此类数据库称为预设数据库,另一种是使用代码生成的数据库。...

大学霸
38分钟前
4
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部