讓咱們來看看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或任何其餘語言功能時,這個相同的概念很是有用。
若是您已熟悉轉換器,請隨意跳過此部分。
有些人可能想知道咱們將如何使用還沒有實現的語言功能!
JavaScript是一種不斷髮展的語言,它帶有一些將JavaScript編譯成JavaScript的轉換器 。在表面上可能聽起來不是頗有幫助,但我向你保證!
它容許咱們編寫最新版本的JavaScript - 甚至包括0階段提案 - 而且仍然可以在當今的運行時環境中執行它,如Web瀏覽器和Node.js.它經過將咱們的代碼更改成爲舊版本的JavaScript編寫而實現此目的。
Babel是最受歡迎的JavaScript轉發器之一。咱們將在立刻使用它。
爲此,您能夠在新目錄中運行如下命令:
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" ]}
如今你準備開始寫一些測試了!
在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
在我看來,這種方法是:
這裏是可選連接的地方。您能夠像這樣使用它:
console.log(data.user?.address?.street); // undefined
那更容易,對吧?如今咱們已經看到了這個功能的用處,咱們能夠繼續深刻研究。
因此咱們來寫一個測試!
如今咱們看到可選連接保持了點符號的先前功能。接下來,讓咱們爲不愉快的路徑添加一個測試。
如下是可選連接如何用於數組屬性訪問:
有時咱們不知道函數是否在Object中實現。
一個常見的例子是當您使用Web瀏覽器時。某些舊版瀏覽器可能沒有某些功能。值得慶幸的是,咱們可使用可選連接來檢測函數是否已實現!
若是鏈不完整,表達式將不會執行。在幕後,表達式大體轉變爲:
value == null ? value[some expression here]: undefined;
在可選鏈操做符以後沒有什麼?若是值未定義或爲null,則將執行。咱們能夠在如下測試中看到該規則的實際應用:
有了它!可選連接減小了對if語句,lodash等導入庫以及使用&&進行連接的需求。
一句警告: 您可能會注意到使用此可選鏈帶來了一些最小的開銷。您檢查的每一個級別?必須包含在引擎蓋下的某種條件邏輯中。若是過分使用,將致使性能損失。當你收到或建立對象時,我建議使用它進行某種對象驗證。這將限制對這些檢查的需求,從而限制性能損失。
這是該提案的連接。我也會在這篇文章的底部複製它,以便您能夠在一個地方看到全部提案連接!
合併:融合或融合在一塊兒
如下是咱們在JavaScript中看到的一些常見操做:
您可能已經看到它像這樣:
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。
在函數式編程中,咱們有一個術語「組合」,它是將多個函數調用連接在一塊兒的行爲。每一個函數接收前一個函數的輸出做爲其輸入。如下是咱們在純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!"
這種串聯是如此常見,以致於組合函數存在於大多數功能庫中,如lodash和ramda。
使用新的管道運算符,您能夠跳過第三方庫並按以下所示編寫上述內容:
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...