1. 程式人生 > >ES2019 中的 JavaScript 新特性

ES2019 中的 JavaScript 新特性

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/

歡迎關注我的個人公眾號 —— 紅薯胡說

相關推薦

ES2019 JavaScript 特性

JavaScript 從成立之初就已經走了很長一段路,提供了許多新的功能,這些功能是專門設計來使該語言更加人性化和提升效率。以下是

Spring Framework 5 特性

jpg 幹凈 map 避免 strong findbugs ora htm 習慣 Spring Framework 5 中的新特性 Spring 5 如何利用 Java 8 的函數式語法和一種新的反應式編程模型 Alex Theedom2017 年 10 月 18 日

Java 8 特性Streams

Stream 作為 Java 8 的一大亮點,它與 java.io 包裡的 InputStream 和 OutputStream 是完全不同的概念。 使用 Stream API 無需編寫一行多執行緒的程式碼,就可以很方便地寫出高效能的併發程式。所以說,Java 8 中首次出現的 java.util.

Vue高版本一些特性的使用詳解

一、深度作用選擇器( >>> ) 嚴格來說,這個應該是vue-loader的功能。”vue-loader”: “^12.2.0” 在專案開發中,如果業務比較複雜,特別像中臺或B端功能頁面都不可避免的會用到第三方元件庫,產品有時會想對這些元件進行一些UI方面的定

Vue高版本一些特性的使用

主要包括以下幾點: 深度作用選擇器( >>> ) 我在另一篇文章中也有提到這點Vue: scoped 樣式與 CSS Module 對比 元件配置項inheritAttrs、元件例項屬性$attrs和$listeners 發生在父子元件之間

Java8特性Optional

ble clas 很多 tps .com util 調用 存在 bsp Optional 類是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調用get()方法會返回該對象。Optional 是個容器:它可以保存類型T的值,或者僅僅保存n

PHP 5.3、5.4、5.5、5.6 特性

PHP 5.6 1、可以使用表示式定義常量 https://php.net/manual/zh/migration56.new-features.php 在之前的 PHP 版本中,必須使用靜態值來定義常量,宣告屬性以及指定函式引數預設值。 現在你可以使用包括數值、字串字面量以及其他常量在

hibernate4.1版本特性和hibernate3.3部分區別

1.資料庫方言設定 <property name=”dialect”>org.hibernate.dialect.MySQL5Dialect</property> 在3.3版本中連線MySQL資料庫只需要指明MySQLDialect即

2019 年的 JavaScript 特性學習指南

昨天在瀏覽 Babel 網站時,看到它的 blog 有一篇新的文章,說 Babel 釋出了新的程式碼支援 class 的私有屬性和方法。 這著實讓我頭腦混亂,到底在哪可以瞭解到最新的規範?而這些規範又是否被支援?支援到什麼程度?完全沒有頭緒。 自從 ES6 規範釋出以來,帶來很多新的特性,而我們在消化這些

C++特性:引用

先放一個例子 swap函式對比(作用,交換兩個數的數值) void swap(int *a, int *b)//使用指標 { int temp = *a; *a = *b; *b = temp; return ; }

Spring 4.x框架特性---4.1功能和提升

JMS的改善 Spring4.1通過引入帶有@JmsListener註解的bean方法給註冊JMS監聽端點提供一個更加簡單的基礎設施。XML名稱空間已經被增強,以便支援這種新的樣式(jms:annotation-driven),並它還可以使用Java配置(@EnableJm

MVC5路由特性

 1、什麼是Attribute路由?怎麼樣啟用Attribute路由?   微軟在 ASP.NET MVC5 中引入了一種新型路由:Attribute路由,顧名思義,Attribute路由是通過Attribute來定義路由。當然,MVC5也支援以前定義路由的方式,你可以

React 16.0特性——portal及其注意點

簡要介紹:React16.0中釋出了很多新特性,我們來看portal,React提供了一個頂級API—portal,用來將子節點渲染到父節點之外的dom節點 1.基本用法 (1)在React15.X版本中,我們只能講子節點在父節點中渲染,基本用法如下:

七種武器:JavaScript 特性閃亮登場

JavaScript(或ECMA Script) 是一門不斷髮展的語言,有許多關於如何前進的建議和想法。TC39(技術委員會39)是負責定義JS標準和特性的委員會,今年他們非常活躍。以下是目前處於“Stage 3階段”的一些提案摘要,這是“完成”之前的最後一個階段。這意味著這些特性將很快在瀏覽器和其他引擎中實

(資料科學學習手札73)盤點pandas 1.0.0特性

本文對應指令碼及資料已上傳至我的Github倉庫https://github.com/CNFeffery/DataScienceStudyNotes 1 簡介   毫無疑問pandas已經成為基於Python的資料分析領域最重要的包,而就在最近,pandas終於迎來了1.0.0版本,對於pandas來說這

【VS2017特性】在VS調試javascript腳本

www projects 解決方案 下界 轉載 啟用 span 閱讀 版權 1 概述 VS2017可以調試JS,本篇文章簡要概述VS2017關於啟用和關閉VS調試功能。 2 具體內容 當開啟VS2017JS調試功能時,我們用VS2017打

ES6特性Javascript的Map和WeakMap物件

  Map物件   Map物件是一種有對應 鍵/值 對的物件, JS的Object也是 鍵/值 對的物件 ;   ES6中Map相對於Object物件有幾個區別:   1:Object物件有原型, 也就是說他有預設的key值在物件上面, 除非我們使用Object.create(null)建立一個沒有原型

Java 9 的 9 個特性

不想 行為 添加元素 ase 結合 quest 簡單 通過 this Java 8 發布三年多之後,即將快到2017年7月下一個版本發布的日期了。 你可能已經聽說過 Java 9 的模塊系統,但是這個新版本還有許多其它的更新。 這裏有九個令人興奮的新功能將與 Java 9

ArcGIS API for JavaScript 4.4學習筆記[] AJS4.4和AJS3.21特性

ack 讀取 port 不同 ide evel arc ges wfs ESRI官網悄無聲息突然更新4.4和3.21,公眾號也沒有什麽消息。照例,給大家看看這次更新有什麽新特性吧。 1. AJS 4.4 官方更新日誌:點我,比較詳細。我在這裏抽一些主幹作為說明。 1.1

PHP7我們應該學習會用的特性

默認 很多 處理 strong 支持 體驗 int 補充 urn PHP7於2015年11月正式發布,本次更新可謂是PHP的重要裏程碑,它將帶來顯著的性能改進和新特性,並對之前版本的一些特性進行改進。本文小編將和大家一起來了解探討PHP7中的新特性。 1. 標量類型聲明 我