三個值得期待的JavaScript新功能!

讓咱們來看看JavaScript中一些有用的即將推出的功能。您將看到他們的語法,連接以及時瞭解他們的進度,咱們將編寫一個小型測試套件,以展現如何當即開始使用這些提案!javascript

JavaScript是如何更新迭代的

若是您已經熟悉Ecma TC39委員會如何決定並處理JavaScript語言的變動,請隨意跳過此部分。java

對於咱們其餘對JavaScript編程語言如何發展感到好奇的人,我想快速概述一下這個過程。node

JavaScript是一種名爲ECMAScript的語言標準的實現,它被建立用於標準化語言的全部實現,由於它是在Web瀏覽器的早期發展而來的。react

已經有八個版本的ECMAScript標準 ,有七個版本(第四版被放棄)。git

每一個JavaScript引擎開始實現每次發佈後指定的更改。此圖表將顯示並不是每一個引擎都實現每一個功能,而且某些引擎須要比其餘引擎更長的時間來實現這些功能。雖然這可能看起來不是最佳的,但我相信它比沒有標準更好!es6

建議

每一個ECMAScript版本都通過審覈提案的過程。若是提案被認爲有用且向後兼容,則將包含在下一版中。github

提案有五個階段,在本文檔中概述。每一個提案都是最初提出的「strawman」或stage 0。在這個級別,他們要麼還沒有提交給技術委員會,要麼還沒有被拒絕,但仍未達到進入下一階段的標準。數據庫

下面顯示的提案都不屬於第0階段。express

做爲我的推薦,我想鼓勵讀者避免在生產應用程序中使用0階段提案,直到它們處於不穩定的階段。此建議的目的只是爲了不在提案被放棄或完全更改時出現問題。npm

測試套件

編程功能的介紹一般會顯示脫離上下文的代碼段,或者使用這些功能來構建應用程序。因爲我是TDD的忠實粉絲,我相信更好的方法來了解功能的做用是測試它。

咱們將使用Jim Newkirk創造的學習測試來實現這一目標 _._,咱們編寫的測試將使斷言不是關於咱們本身的代碼,而是關於編程語言自己。在學習第三方API或任何其餘語言功能時,這個相同的概念很是有用。

Transpilers

若是您已熟悉轉換器,請隨意跳過此部分。

有些人可能想知道咱們將如何使用還沒有實現的語言功能!

JavaScript是一種不斷髮展的語言,它帶有一些將JavaScript編譯成JavaScript的轉換器 。在表面上可能聽起來不是頗有幫助,但我向你保證!

它容許咱們編寫最新版本的JavaScript - 甚至包括0階段提案 - 而且仍然可以在當今的運行時環境中執行它,如Web瀏覽器和Node.js.它經過將咱們的代碼更改成爲舊版本的JavaScript編寫而實現此目的

Babel是最受歡迎的JavaScript轉發器之一。咱們將在立刻使用它。

步驟

您須要安裝Node.jsNPM

爲此,您能夠在新目錄中運行如下命令:

npm init -f && npm i ava@1.0.0-beta.3 @babel/preset-env@7.0.0-beta.42 @babel/preset-stage-0@7.0.0-beta.42 @babel/register@7.0.0-beta.42 @babel/polyfill@7.0.0-beta.42 @babel/plugin-transform-runtime@7.0.0-beta.42 @babel/runtime@7.0.0-beta.42 --save-dev

而後,您須要將如下內容添加到package.json文件中:

"scripts": {  "test": "ava"},"ava": {      "require": [          "@babel/register",    "@babel/polyfill"     ]  }

最後建立一個.babelrc文件:

{    "presets": [        ["@babel/preset-env", {            "targets": {                "node": "current"            }        }],        "@babel/preset-stage-0"    ],    "plugins": [        "@babel/plugin-transform-runtime"  ]}

如今你準備開始寫一些測試了!

1.可選連接

在JavaScript中,咱們一直在使用Objects。有時這些物體沒有咱們指望的確切形狀。下面你會找到一我的爲的數據對象示例 - 多是從數據庫或API調用中檢索到的。

const data = {  user: {    address: {      street: 'Pennsylvania Avenue',    },   },};

哎呀,看起來這個用戶沒有完成註冊:

const data = {  user: {},};

假設,當我嘗試訪問應用程序儀表板上的街道時,我會收到如下錯誤:

console.log(data.user.address.street);
// Uncaught TypeError: Cannot read property 'street' of undefined

爲避免這種狀況,咱們目前必須訪問「street」屬性,以下所示:

const street = data && data.user && data.user.address && data.user.address.street;console.log(street);
// undefined

在我看來,這種方法是:

  1. 不美觀
  2. 繁重
  3. 囉嗦

這裏是可選連接的地方。您能夠像這樣使用它:

console.log(data.user?.address?.street);
// undefined

那更容易,對吧?如今咱們已經看到了這個功能的用處,咱們能夠繼續深刻研究。

因此咱們來寫一個測試!

如今咱們看到可選連接保持了點符號的先前功能。接下來,讓咱們爲不愉快的路徑添加一個測試。

如下是可選連接如何用於數組屬性訪問:

有時咱們不知道函數是否在Object中實現。

一個常見的例子是當您使用Web瀏覽器時。某些舊版瀏覽器可能沒有某些功能。值得慶幸的是,咱們可使用可選連接來檢測函數是否已實現!

若是鏈不完整,表達式將不會執行。在幕後,表達式大體轉變爲:

value == null ? value[some expression here]: undefined;

在可選鏈操做符以後沒有什麼?若是值未定義或爲null,則將執行。咱們能夠在如下測試中看到該規則的實際應用:

有了它!可選連接減小了對if語句,lodash等導入庫以及使用&&進行連接的需求。

一句警告: 您可能會注意到使用此可選鏈帶來了一些最小的開銷。您檢查的每一個級別?必須包含在引擎蓋下的某種條件邏輯中。若是過分使用,將致使性能損失。當你收到或建立對象時,我建議使用它進行某種對象驗證。這將限制對這些檢查的需求,從而限制性能損失。

連接

這是該提案的連接。我也會在這篇文章的底部複製它,以便您能夠在一個地方看到全部提案連接!

2. 空值合併

合併:融合或融合在一塊兒

如下是咱們在JavaScript中看到的一些常見操做:

  1. 檢查未定義或空值
  2. Defaulting Values
  3. 確保0,false和空字符串不是默認值。

您可能已經看到它像這樣:

value != null ? value : 'default value';

或者這樣:

value || 'default value'

問題是,對於第二個實現,咱們的第三個操做條件不知足。在這種狀況下,數字零,布爾值false和空字符串都被視爲false。這就是咱們必須明確檢查null和undefined的緣由。

value != null

這與:

value !== null && value !== undefined

這就是新提案(無效合併)的用武之地。如今咱們能夠這樣作:

value ?? 'default value';

這能夠保護咱們不會意外地默認那些虛假的值,可是仍然會在沒有三元和!= null檢查的狀況下捕獲null和undefined。

如今咱們看到了語法,咱們能夠編寫一個簡單的測試來驗證它是如何工做的。

您能夠在測試中看到它使用null,undefined和void 0的默認值(計算結果爲undefined)。它不會默認虛假值,如0,''和false。在這裏查看GitHub。

3. 管道運算符

在函數式編程中,咱們有一個術語「組合」,它是將多個函數調用連接在一塊兒的行爲。每一個函數接收前一個函數的輸出做爲其輸入。如下是咱們在純JavaScript中討論的一個示例:

function doubleSay (str) {  return str + ", " + str;}
function capitalize (str) {  return str[0].toUpperCase() + str.substring(1);}
function exclaim (str) {  return str + '!';}
let result = exclaim(capitalize(doubleSay("hello")));result //=> "Hello, hello!"

這種串聯是如此常見,以致於組合函數存在於大多數功能庫中,如lodashramda

使用新的管道運算符,您能夠跳過第三方庫並按以下所示編寫上述內容:

let result = "hello"  |> doubleSay  |> capitalize  |> exclaim;result //=> "Hello, hello!"

目的是使_鏈_更具可讀性。它也將在將來部分應用中很好地工做,或者如今它能夠像這樣實現:

let result = 1  |> (_ => Math.max(0, _));result //=> 1
let result = -5  |> (_ => Math.max(0, _));result //=> 0

如今咱們看到了語法,咱們能夠開始編寫測試了!

您可能注意到的一件事是,一旦將異步函數添加到管道,您必須等待該值。這是由於價值已成爲承諾。有一些建議的更改支持|>等待asyncFunction,但還沒有實現或決定。

好了,既然你已經看到了這些建議的實際應用,我但願你可以嘗試一下這些建議!

學習測試的完整代碼能夠在這裏找到

如下是全部四個提案連接 :

tc39/proposal-optional-chaining _Contribute to proposal-optional-chaining development by creating an account on GitHub._github.com[](https://github.com/TC39/propo...

tc39/proposal-nullish-coalescing _proposal-nullish-coalescing - Nullish coalescing proposal x ?? y_github.com[](https://github.com/tc39/propo...

tc39/proposal-partial-application _proposal-partial-application - Proposal to add partial application to ECMAScript_github.com[](https://github.com/tc39/propo...

tc39/proposal-pipeline-operator _proposal-pipeline-operator - A proposal for adding the simple-but-useful pipeline operator to JavaScript._github.com[](https://github.com/tc39/propo...

相關文章
相關標籤/搜索