国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

[譯] TC39,ECMAScript 和 JavaScript 的未來(Part 1)

ziwenxie / 1393人閱讀

摘要:由很多令人興奮的功能,如對象的解析與剩余,異步迭代器,方法和更好的正則表達式支持。迭代可以是任何遵循迭代器協議的對象。迭代器方法應該返回一個具有方法的對象。

原文:TC39, ECMAScript, and the Future of JavaScript
作者:Nicolás Bevacqua

譯者序

很榮幸能夠和 Nicolás Bevacqua 同臺分享。Nicolás Bevacqua 分享了《the Future of Writing JavaScript 》,我在其后分享了《面向前端開發者的V8性能優化》。如果想了解更多 V8 知識可以關注我的專欄:V8 引擎。

由于 Nicolás Bevacqua 是英文分享,現場由很多聽眾都沒有太明白,會后我聯系了 Nicolás Bevacqua 爭得大神同意后將其文章翻譯為中文。

大神微信玩的很溜,很快就學會了搶紅包。

再次感謝 Nicolás Bevacqua 的精彩分享。

譯文:

上周,我在中國深圳的騰訊前端大會上發表了與本文同名的演講。在這篇文章中,我根據 PonyFoo 網站的格式重新編輯了一遍。我希望你喜歡它!

TC39 是什么?

TC39 指的是技術委員會(Technical Committee)第 39 號。它是 ECMA 的一部分,ECMA 是 “ECMAScript” 規范下的 JavaScript 語言標準化的機構。

ECMAScript 規范定義了 JavaScript 如何一步一步的進化、發展。其中規定了:

字符串 "A" 為什么是 NaN

字符串 "A" 為什么不等于 NaN

NaN 為什么是 NaN,但卻不等于 NaN

并介紹了為什么 Number.isNaN 是一個很好的 idea ...

isNaN(NaN) // true
isNaN("A") // true
"A" == NaN // false
"A" === NaN // false
NaN === NaN // false

// … 解決方案!

Number.isNaN("A") // false
Number.isNaN(NaN) // true

它還解釋了正零與負零什么情況下相等,什么情況下不相等。。。

+0 == -0 // true
+0 === -0 // true
1/+0 === 1 / -0 // false

而且 js 中還有很多奇技淫巧,例如只使用感嘆號、小括號、方括號和加號來編碼任何有效的 JavaScript 表達式。可以在 JSFuck 網站了解更多關于如何只使用 +!()[] 編寫 JavaScript 代碼的技巧。

不論如何,TC39 所做的不懈努力是難能可貴的。

TC39 遵循的原則是:分階段加入不同的語言特性。一旦提案成熟,TC39 會根據提案中的變動來更新規范。直到最近,TC39 依然依賴基于 Microsoft Word 的比較傳統的工作流程。但 ES3 出來之后,他們花了十年時間,幾乎沒有任何改變,使其達到規范。之后,ES6 又花了四年才能實現。

顯然,他們的流程必須改善。

自 ES6 出來之后,他們精簡了提案的修訂過程,以滿足現代化開發的需求。新流程使用 HTML 的超集來格式化提案。他們使用 GitHub pull requests,這有助于增加社區的參與,并且提出的提案數量也增加了。這個規范現在是一個 living standard,這意味著提案會更快,而且我們也不用等待新版本的規范出來。

新流程涉及四個不同的 Stage。一個提案越成熟,越有可能最終將其納入規范。

Stage 0

任何尚未提交作為正式提案的討論、想法變更或者補充都被認為是第 0 階段的“稻草人”提案。只有 TC39 的成員可以創建這些提案,而且今天就有若干活躍的“稻草人”提案。

目前在 Stage 0 的提案包括異步操作的 cancellation tokens , Zones 作為 Angular 團隊的一員,提供了很多建議。Stage 0 包括了很多一直沒有進入 Stage 1 的提案。

在這篇文章的后面,我們將仔細分析一部分提案。

Stage 1

在 Stage 1,提案已經被正式化,并期望解決此問題,還需要觀察與其他提案的相互影響。在這個階段的提案確定了一個分散的問題,并為這個問題提供了具體的解決方案。

Stage 1 提議通常包括高階 API 描述(high level AP),使用示例以及內部語義和算法的討論。這些建議在通過這一過程時可能會發生重大變化。

Stage 1 目前提案的例子包括:Observable、do 表達式、生成器箭頭函數、Promise.try。

Stage 2

Stage 2 的提案應提供規范初稿。

此時,語言的實現者開始觀察 runtime 的具體實現是否合理。該實現可以使用 polyfill 的方式,以便使代碼可在 runtime 中的行為負責規范的定義; javascript 引擎的實現為提案提供了原生支持; 或者可以 Babel 這樣的編譯時編譯器來支持。

目前 Stage 2 階段的提案有 public class fields、private class fields、decorators、Promise#finally、等等。

Stage 3

Stage 3 提案是建議的候選提案。在這個高級階段,規范的編輯人員和評審人員必須在最終規范上簽字。Stage 3 的提案不會有太大的改變,在對外發布之前只是修正一些問題。

語言的實現者也應該對此提案感興趣 - 如果只是提案卻沒有具體實現去支持這個提案,那么這個提案早就胎死腹中了。事實上,提案至少具有一個瀏覽器實現、友好的 polyfill或者由像 Babel 這樣的構建時編譯器支持。

Stage 3 由很多令人興奮的功能,如對象的解析與剩余,異步迭代器,import() 方法和更好的 Unicode 正則表達式支持。

Stage 4

最后,當規范的實現至少通過兩個驗收測試時,提案進入 Stage 4。

進入 Stage 4 的提案將包含在 ECMAScript 的下一個修訂版中。

異步函數,Array#includes 和 冪運算符 是 Stage 4 的一些特性。

保持最新 Staying Up To Date

我(原文作者)創建了一個網站,用來展示當前提案的列表。它描述了他們在什么階段,并鏈接到每個提案,以便您可以更多地了解它們。

網址為 proptt39.now.sh。

目前,每年都有新的正式規范版本,但精簡的流程也意味著正式版本變得越來越不相關。現在重點放在提案階段,我們可以預測,在 ES6 之后,對該標準的具體修訂的引用將變得不常見。

提案 Proposals

我們來看一些目前正在開發的最有趣的提案。

Array#includes (Stage 4)

在介紹 Array#includes 之前,我們不得不依賴 Array#indexOf 函數,并檢查索引是否超出范圍,以確定元素是否屬于數組。

隨著 Array#includes 進入 Stage 4,我們可以使用 Array#includes 來代替。它補充了 ES6 的 Array#findArray#findIndex

[1, 2].indexOf(2) !== -1 // true
[1, 2].indexOf(3) !== -1 // false
[1, 2].includes(2) // true
[1, 2].includes(3) // false
異步函數(Stage 4)

當我們使用 Promise 時,我們經常考慮執行線程。我們有一個異步任務 fetch,其他任務依賴于 fetch 的響應,但在收到該數據之前程序時阻塞的。

在下面的例子中,我們從 API 中獲取產品列表,該列表返回一個 Promise。當 fetch 相應之后,Promise 被 resolve。然后,我們將響應流作為 JSON 讀取,并使用響應中的數據更新視圖。如果在此過程中發生任何錯誤,我們可以將其記錄到控制臺,以了解發生了什么。

fetch("/api/products")
  .then(response => response.json())
  .then(data => {
    updateView(data)
  })
  .catch(err => {
    console.log("Update failed", err)
  })

異步函數提供了語法糖,可以用來改進我們基于 Promise 的代碼。我們開始逐行改變以上基于 Promise 的代碼。我們可以使用 await 關鍵字。當我們 await 一個 Promise 時,我們得到 Promise 的 fulled 狀態的值。

Promise 代碼的意思是:“我想執行這個操作,然后(then)在其他操作中使用它的結果”。

同時,await 有效地反轉了這個意思,使得它更像:“我想要取得這個操作的結果”。我喜歡,因為它聽起來更簡單。

在我們的示例中,響應對象是我們之后獲取的,所以我們將等待(await)獲取(fetch)操作的結果,并賦值給 response 變量,而不是使用 promisethen

原文:we’ll flip things over and assigned the result of await fetch to the response variable

+ const response = await fetch("/api/products")
- fetch("/api/products")
    .then(response => response.json())
    .then(data => {
      updateView(data)
    })
    .catch(err => {
      console.log("Update failed", err)
    })

我們給 response.json() 同樣的待遇。我們 await 上一次的操作并將其賦值給 data 變量。

  const response = await fetch("/api/products")
+ const data = await response.json()
-   .then(response => response.json())
    .then(data => {
      updateView(data)
    })
    .catch(err => {
      console.log("Update failed", err)
    })

既然 then 鏈已經消失了,我們就可以直接調用 updateView 語句了,因為我們已經到了之前代碼中的 Promise then 鏈的盡頭,我們不需要等待任何其他的 Promise。

  const response = await fetch("/api/products")
  const data = await response.json()
+ updateView(data)
-   .then(data => {
-     updateView(data)
-   })
    .catch(err => {
      console.log("Update failed", err)
    })

現在我們可以使用 try/catch 塊,而不是 .catch,這使得我們的代碼更加語義化。

+ try {
    const response = await fetch("/api/products")
    const data = await response.json()
    updateView(data)
+ } catch(err) {
- .catch(err => {
    console.log("Update failed", err)
+ }
- )}

一個限制是 await 只能在異步函數內使用。

+ async function run() {
    try {
      const response = await fetch("/api/products")
      const data = await response.json()
      updateView(data)
    } catch(err) {
      console.log("Update failed", err)
    }
+ }

但是,我們可以將異步函數轉換為自調用函數表達式。如果我們將頂級代碼包在這樣的表達式中,我們可以在代碼中的任何地方使用 await 表達式。

一些社區希望原生支持頂級塊作用于的 await,而另外一些人則認為這會對用戶造成負面影響,因為一些庫可能會阻塞異步加載,從而大大減緩了我們應用程序的加載時間。

+ (async () => {
- async function run() {
    try {
      const response = await fetch("/api/products")
      const data = await response.json()
      updateView(data)
    } catch(err) {
      console.log("Update failed", err)
    }
+ })()
- }

就個人而言,我認為在 JavaScript 性能中已經有足夠的空間來應對這種愚蠢的事情,來優化初始化的庫使用 await 的行為。

請注意,您也可以在 non-promise 的值前面使用 await,甚至編寫代碼 await (2 + 3)。在這種情況下,(2 + 3) 表達的結果會被包在 Promise 中,作為 Promise 的最終值。5 成為這個 await 表達式的結果。

請注意,await 加上任何 JavaScript 表達式也是一個表達式。這意味著我們不限制 await 語句的賦值操作,而且我們也可以把 await 函數調用作為模板文字插值的一部分。

`Price: ${ await getPrice() }`

或作為另一個函數調用的一部分...

renderView(await getPrice())

甚至作為數學表達式的一部分。

2 * (await getPrice())

最后,不管它們的內容如何,??異步函數總是返回一個 Promise。這意味著我們可以添加 .then.catch 等異步功能,也可以使用 await 獲取最終的結果。

const sleep = delay => new Promise(resolve =>
  setTimeout(resolve, delay)
)

const slowLog = async (...terms) => {
  await sleep(2000)
  console.log(...terms)
}

slowLog("Well that was underwhelming")
  .then(() => console.log("Nailed it!"))
  .catch(reason => console.error("Failed", reason))

正如您所期望的那樣,返回的 Promise 與 async 函數返回的值進行運算,或者被 catch 函數來處理任何未捕獲的異常。

異步迭代器(Stage 3)

異步迭代器已經進入了 Stage 3。在了解異步迭代器之前,讓我們簡單介紹一下 ES6 中引入的迭代。迭代可以是任何遵循迭代器協議的對象。

為了使對象可以迭代,我們定義一個 Symbol.iterator 方法。迭代器方法應該返回一個具有 next 方法的對象。這個對象描述了我們的 iterable 的順序。當對象被迭代時,每當我們需要讀取序列中的下一個元素時,將調用 next 方法。value 用來獲取序列中每一個對象的值。當返回的對象被標記為 done,序列結束。

const list = {
  [Symbol.iterator]() {
    let i = 0
    return {
      next: () => ({
        value: i++,
        done: i > 5
      })
    }
  }
}
[...list]
// <- [0, 1, 2, 3, 4]
Array.from(list)
// <- [0, 1, 2, 3, 4]
for (const i of list) {
  // <- 0, 1, 2, 3, 4
}

可以使用 Array.from 或使用擴展操作符使用 Iterables 。它們也可以通過使用 for..of 循環來遍歷元素序列。

異步迭代器只有一點點不同。在這個提議下,一個對象通過 Symbol.asyncIterator 來表示它們是異步迭代的。異步迭代器的方法簽名與常規迭代器的約定略有不同:該 next 方法需要返回 包裝了 { value, done }Promise,而不是 { value, done } 直接返回。

const list = {
  [Symbol.asyncIterator]() {
    let i = 0
    return {
      next: () => Promise.resolve({
        value: i++,
        done: i > 5
      })
    }
  }
}

這種簡單的變化非常優雅,因為 Promise 可以很容易地代表序列的最終元素。

異步迭代不能與數組擴展運算符、Array.fromfor..of 一起使用,因為這三個都專門用于同步迭代。

這個提案也引入了一個新的 for await..of 結構。它可以用于在異步迭代序列上語義地迭代。

for await (const i of items) {
  // <- 0, 1, 2, 3, 4
}

請注意,該 for await..of 結構只能在異步函數中使用。否則我們會得到語法錯誤。就像任何其他異步函數一樣,我們也可以在我們的循環周圍或內部使用 try/catchfor await..of

async function readItems() {
  for await (const i of items) {
    // <- 0, 1, 2, 3, 4
  }
}

更進一步。還有異步生成器函數。與普通生成器函數有些相似,異步生成器函數不僅支持 async await 語義,還允許 await 語句以及 for await..of

(原文第一段:The rabbit hole goes deeper of course. 這是愛麗絲夢游仙境的梗嗎?)

async function* getProducts(categoryUrl) {
  const listReq = await fetch(categoryUrl)
  const list = await listReq.json()
  for (const product of list) {
    const productReq = await product.url
    const product = await productReq.json()
    yield product
  }
}

在異步生成器函數中,我們可以使用 yield* 與其他異步發生器和普通的發生器一起使用。當調用時,異步生成器函數返回異步生成器對象,其方法返回包裹了 { value, done } 的 Promise,而不是 { value, done }

最后,異步生成器對象可以被使用在 for await..of,就像異步迭代一樣。這是因為異步生成器對象是異步迭代,就像普通生成器對象是普通的迭代。

async function readProducts() {
  const g = getProducts(category)
  for await (const product of g) {
    // use product details
  }
}
對象解構與剩余(Stage 3)

從 ES6 開始,我們使用 Object.assign 將屬性從一個或多個源對象復制到一個目標對象上。在下一個例子中,我們將一些屬性復制到一個空的對象上。

Object.assign(
 {},
 { a: "a" },
 { b: "b" },
 { a: "c" }
)

對象解構(spread)提議允許我們使用純語法編寫等效的代碼。我們從一個空對象開始,Object.assign 隱含在語法中。

{
 ...{ a: "a" },
 ...{ b: "b" },
 ...{ a: "c" }
}
// <- { a: "c", b: "b" }

和對象解構相反的還有對象剩余,類似數組的剩余參數。當對對象進行解構時,我們可以使用對象擴展運算符將模式中未明確命名的屬性重建為另一個對象。

在以下示例中,id 顯式命名,不會包含在剩余對象中。對象剩余(rest)可以從字面上讀取為“所有其他屬性都轉到一個名為 rest 的對象”,當然,變量名稱供您選擇。

const item = {
 id: "4fe09c27",
 name: "Banana",
 amount: 3
}
const { id, ...rest } = item
// <- { name: "Banana", amount: 3 }

在函數參數列表中解析對象時,我們也可以使用對象剩余屬性。

function print({ id, ...rest }) {
  console.log(rest)
}
print({ id: "4fe09c27", name: "Banana" })
// <- { name: "Banana" }
動態 import()(Stage 3)

ES6 引入了原生 JavaScript 模塊。與 CommonJS 類似,JavaScript 模塊選擇了靜態語法。這樣開發工具有更簡單的方式從靜態源碼中分析和構建依賴樹,這使它成為一個很好的默認選項。

import markdown from "./markdown"
// …
export default compile

然而,作為開發人員,我們并不總是知道我們需要提前導入的模塊。對于這些情況,例如,當我們依賴本地化來加載具有用戶語言的字符串的模塊時,Stage 3 的動態 import() 提案就很有用了。

import() 運行時動態加載模塊。它為模塊的命名空間對象返回 Promise,當獲取該對象時,系統將解析和執行所請求的模塊及其所有依賴項。如果模塊加載失敗,Promise 將被拒絕。

import(`./i18n.${ navigator.language }.js`)
  .then(module => console.log(module.messages))
  .catch(reason => console.error(reason))

未完。。。。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/83771.html

相關文章

  • 2017-07-02 前端日報

    摘要:前端日報精選譯,和的未來學習筆記箭頭函數學習筆記教程柵格布局卷土重來,用還是為什么我會選擇而不是眾成翻譯原生開發入門完全教程從零到壹全棧部落中文一個端帶文件路徑和顏色的攻城方略譯使用提高應用程序的種方式中自定義操作符修仙 2017-07-02 前端日報 精選 [譯] TC39,ECMAScript 和 JavaScript 的未來(Part 1)ES6學習筆記:箭頭函數_ES6, Ja...

    lemon 評論0 收藏0
  • ECMAScript文檔---序言及1-6章(上)

    摘要:隨后,它出現在公司之后的瀏覽器,以及從微軟從起發布的所有瀏覽器上。標準的第版在年月的大會上被表決接受。第版在年月底大會上被采納。 前言 ??本系列譯文的初衷旨在希望更多人能夠了解關于JS的一些基本概念,遇到原理性的問題時多去翻翻文檔,而不是在社區無休止的重復提出某些在文檔中能夠非常方便快捷就能找到的東西。 ??精力和水平有限,所以暫時只打算嘗試翻譯前面幾章概括性的介紹,同時后面的章節大...

    wind3110991 評論0 收藏0
  • 】關于轉JavaScript 程序員需要知道

    摘要:他們的計劃是,使用微軟開發者們所習慣的其他語言的開發工具所支持的靜態類型,得到更好的代碼。在微軟內部,被和以及團隊所使用,而且它被系的等公司使用。標準的編輯,同時也是微軟項目高級經理的也同意。 本文轉載自:眾成翻譯譯者:文藺鏈接:http://www.zcfy.cc/article/895原文:http://thenewstack.io/javascript-transpilers-n...

    freecode 評論0 收藏0
  • 2017-07-08 前端日報

    摘要:前端日報精選精讀與提案知乎專欄第期認識引擎記錄一次利用工具進行性能優化的真實案例簡書中的使用規則教程繼承的實現方法個人文章中文譯組件渲染性能探索個人文章周刊第期表單性能的改進實踐知乎專欄簡單可重用的圖表庫知乎專欄 2017-07-08 前端日報 精選 精讀 TC39 與 ECMAScript 提案 - 知乎專欄【第989期】認識 V8 引擎記錄一次利用 Timeline/Perform...

    王巖威 評論0 收藏0
  • 三個值得期待JavaScript新功能!

    摘要:每個引擎開始實現每次發布后指定的更改。每個提案都是最初提出的或。此建議的目的只是為了避免在提案被放棄或徹底更改時出現問題。這將限制對這些檢查的需求,從而限制性能損失。這與這就是新提案無效合并的用武之地。這是因為價值已成為承諾。 讓我們來看看JavaScript中一些有用的即將推出的功能。您將看到他們的語法,鏈接以及時了解他們的進度,我們將編寫一個小型測試套件,以展示如何立即開始使用這些...

    UCloud 評論0 收藏0

發表評論

0條評論

ziwenxie

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<