您的位置:首頁>正文

精讀《現代 JavaScript 概覽》

對於web前端的學習有不懂的, 或者不知道學習路線, 不知道學習方法, 不知道該如何扎實能找到工作的朋友, 我還是要推薦下我自己建的前端學習群:523218370, 首先你要是前端黨, 其次不管你是小白還是大牛, 我都挺歡迎, 小白嘛, 主動點多問問題也就學好了, 群裡每天分享乾貨, 包括我自己最近花了一星期整理的一份適合2017年自學的最新web前端資料, 送給大家, 歡迎初學和進階中的小夥伴。

1 引言

我為什麼要選這篇文章呢?

之所以選這篇文章, 是因為非常認同作者寫這兩篇文章的原因. 作者在文中說, 現代 JavaScript 的很多概念和思想在快速被傳播和擴展, 很多新概念出現在前端相關的博客和文檔中, 這些概念對於很多前端開發人員來說, 仍然很陌生. 因此我們有必要來學習一下現代的這些 JavaScript 的概念, 看這些概念在現在 JavaScript 的庫或應用中是怎麼被使用的.

2 內容概要

文章講了很多現代 JavaScript 中的概念, 羅列如下:

純函數和副作用

在瞭解純函數之前, 首先要瞭解副作用. 副作用是指改變了其作用域外的狀態. 副作用的舉例有調用了一個 API, 操作了一個 DOM 節點, 彈出了一個彈窗, 或者改變了一條資料等.

而純函數則是指 函數的返回值僅僅由參數決定, 當給同樣的參數時, 返回值是固定的.

Stateful 和 Stateless (有狀態和無狀態)

Stateless 無狀態, 有點像純函數, 不管理自己的資料或狀態, 結果取決於參數. 而 Stateful, 有狀態, 指的是函數自己有自己的運行狀態, 可以修改自己的狀態. 在現代 JavaScript 開發中, 處理狀態, 顯得很重要.

可變物件與不可變物件

可變物件與不可變物件概念很清楚, 可變物件指的是在創建後值仍可以被改變, 不可變物件指的是創建後值無法被改變.

相比於其他語言, 可變物件與不可變物件在 JavaScript 中更加模糊, 當你瞭解函數式程式設計時, 你會聽到很多不可變對象的好處. 在 JavaScript 中, 你可以通過 Object.freeze(obj), 讓一個物件變得不可變, 但是注意這是淺層的凍結物件, 如果有一個屬性的值是個物件, 那這個物件中的屬性是可以被修改的. 現在 JavaScript 也出現了 npm deep-freeze , Immutable.js 這些庫來幫助你在 JavaScript 中實現不可變物件.

Imperative and Declarative Programming(命令式和聲明式程式設計)

命令式程式設計, 描述一段代碼的邏輯怎麼被顯式調用去改變程式的狀態. 聲明式程式設計, 描述一段代碼的邏輯, 而不需要描述如何完成這段邏輯.

JavaScript 可以同時被寫為命令式和聲明式程式設計方式, 但是隨著函數式程式設計的興起, 聲明式程式設計將變得更加普遍.

高階函數

函數作為 JavaScript 的一等公民, 可以跟普通資料類型一樣, 被存儲, 或者被作為值傳參. 而高階函數就是一種函數 可以接收另外一個函數作為入參, 或者返回一個函數作為結果.

函數式程式設計 FP

上面我們瞭解的 純函數, 無狀態, 不可變物件, 命令式程式設計, 和高階函數, 都是很重要的函數式程式設計組成. 函數式程式設計通過以下方式包含上述概念:

關鍵函數實現使用純函數, 沒有副作用.

資料不可變

函數 無狀態

聲明式代碼去管理副作用和執行命令式程式設計

Hot and Cold Observables

Observables 和陣列類似, 只不過陣列是被保存在記憶體中, 而 Observables 的每一個元素則是非同步加入進來. 我們可以訂閱這些 observables.

Hot Observables 容易會被執行, 即使我們沒有訂閱它們. 比如說 使用者的操作介面的 按鈕點擊事件, 滑鼠移動, 視窗大小改變, 這些都是 Hot Observables. 而 cold observable 則是需要我們去訂閱, 並且會在我們訂閱的時候開始執行.

回應式程式設計 RP

回應式程式設計, 可以看作是面向非同步事件流的程式設計, 聲明式的表述去做什麼, 而不是怎麼做.

函數式回應型程式設計 FRP

函數式回應型程式設計簡而言之,就是對事件或者行為給予聲明式的回饋. FRP 具有兩個很明顯的特點:

函數或者類型有明確的定義

操作的是連續變化的值

作用域和閉包

閉包作為最常見的面試題經常被提及, 但是很多資深的前端開發都解釋不清楚閉包, 即使他們理解閉包. 作者首先介紹了全域作用域和局部作用域, 作用域作為許多 JS 開發人員最開始學習的知識, 理解作用域對於編寫優秀的代碼至關重要.

閉包的形成在於, 當一個在函數內聲明的函數可以引用外部函數的區域變數. 就形成了閉包.

單向資料流程和雙向資料流程

隨著現在各種 SPA 框架的興起, 理解資料流程概念, 對於現在 JS 開發者越來越重要, React 被認為是單向資料流程的典範, 使用 Model 作為唯一的資料來源, 控制 View 的渲染. 在 View 層用事件的方式通知 Model 更新, 在反應到 View 層的變化上. 資料沿著一個方向流動, UI 永遠不會更新 Model, 而是通過事件或者 setState 方法.

在雙向資料綁定中, 資料是在兩個方向上流動的, JS可以更新 Model 資料, View 層 也可以更新 Model 資料. AngularJs 的1.x 版本是雙向資料流程的典型實現.

早在2009年, 雙向綁定是 Angualr 最受歡迎的特性之一, 但是 Angular 把這一特性拋棄了. 現在很多流行的框架和庫都使用了單向資料流程(React,Angular,Inferno,Redux等). 單向資料流程宣導的是清晰的架構, 資料流程動更加清晰和易管理. 對於單向資料流程來說說了點View自動更新資料的便利, 但也得到了清晰的資料流程.

JS框架中的變化偵測: 髒檢查, getter 和 setter, 虛擬 DOM

變化偵測對於現代 SPA應用來說很重要. 當使用者更新一些內容時, 應用必須以一種方法知道這種變化, 並做出反應更新.

AngularJS 1.x 使用的是髒檢查的方式, 具體做法是對View 中涉及到的 Model 進行深度比較. 髒檢查的優點在於它的簡單和可預測, 不涉及到 API 和物件的變更. 但是正因為涉及到大量比較, 也很低效.

Ember 和 Backbone 是使用getters 和 setters 來做變化偵測, 這樣涉及到資料修改時, 都會觸發變更事件. 而 React 是使用了虛擬 Dom 來做變化偵測, React 通過 setState方法來通知變更, 使用虛擬 Dom 來比較是否發生了資料變化.

Web Components元件

Web 元件是 Web 平臺上可複用的基礎組件, 而 Web Components 則定義了一些規範來實現這些可複用組件.

規範包括:

自訂元素

HTML Template

Shadow Dom

HTML imports 引入

Web Components 本身並不能代替 SPA框架的功能, 但是它的想法和核心概念, 在很多 SPA 框架中都有體現.

Smart 和 Dumb 元件

現在Web 的開發嚴重依賴元件, 而很多時候我們把元件分成 Smart 元件和 Dumb 元件.

Smart 元件, 又叫容器元件, 在元件內處理各種業務邏輯, 通常也管理 Dumb 元件,響應 Dumb 元件的事件.

Dumb 元件, 又叫展示組件, 通常被寫成純函數, 依賴於外部的資料和方法, 專注於展現資料.

JIT 編譯

Just-In-time(JIT)編譯指的是代碼的運行時, 被編譯成機器代碼的過程. 在JavaScript 運行時, JIT 能夠找到代碼的特定模式, 而這些模式可以讓 JavaScript 更快的被執行.

AOT 編譯

Ahead-Of-Time(AOT), 指的是編寫的代碼在運行之前, 被翻譯成機器代碼的過程. AOT 給 tree shaking 帶來了可能, 使用 AOT 預編譯, 對於生產環境下的代碼有以下好處:

更少的非同步請求, 範本和樣式內聯在 JS 內

更小的體積

更早的檢查到範本錯誤

更好的安全性

Tree Shaking

Tree Shaking 是指打包 JS 模組時, 通過對代碼的靜態分析, 排除掉不用的代碼的機制.

Tree Shaking 技術建立在 ES2015 模組的, import 和 export上, 支持我們導入特定的內容,而不是整個庫.

import { BehaviorSubject } from 'rxjs/BehaviorSubject';

這樣我們只導入了 BehaviorSubject, 而沒有導入整個 Rxjs 庫.

3 精讀

文中講到的現代 JavaScript 已經很多了, 再對理解的現代 JavaScript 補充幾條:

Dependent injection(依賴注入)

通過控制反轉,父級不需要關心子實現細節,將子類可能用到的實例都初始化好,由子類決定引入哪些依賴。還有一個好處是維持了單實例,這一點在資料流程中尤為重要,如果 store 不是單例的,那資料流程必然亂了套,既希望傳給子類使用,又要維持單例,依賴注入是很好的解決方案。

Symbol Reflect Proxy

Symbol 是 ES6中加入的一種新的資料類型, 每一個 Symbol 都是獨一無二的, 不與其它 Symbol 重複.

ES6中的 Proxy , 則是通過 Proxy 方法, 實現對於物件的一層攔截. 提供一種機制, 代理物件的操作. 而 Reflect 是一個內置的物件,它提供可攔截 JavaScript 操作的方法。方法與代理處理常式的方法相同。

這三篇文章非常詳細介紹了這三位 API:symbol, reflect, proxy

Server rendering

前端對後端渲染的熱度降了很多,主要是盲目跟風的氛圍消停了,真正需要的團隊已經穩定的用起來了。後端渲染的理念很新穎,一定程度説明了 html 認識到自己的不足,就像 Angular, React, Vue 對 webComponents 的衝擊一樣,或許未來十年可以用上 ECMAScript 標準提供的功能,但業務不能等待技術,現在唯有不斷折騰,直到被消滅或者招安。

4 總結

伴隨著各種框架的熱度, 理解這些現代 JavaScript 概念變得越來越重要, 大家可以以這個作為概覽, 詳細去學習和瞭解現代 JavaScript 的概念.

對於web前端的學習有不懂的,或者不知道學習路線,不知道學習方法,不知道該如何扎實能找到工作的朋友,我還是要推薦下我自己建的前端學習群:523218370,首先你要是前端黨,其次不管你是小白還是大牛,我都挺歡迎,小白嘛,主動點多問問題也就學好了,群裡每天分享乾貨,包括我自己最近花了一星期整理的一份適合2017年自學的最新web前端資料,送給大家,歡迎初學和進階中的小夥伴。

在雙向資料綁定中, 資料是在兩個方向上流動的, JS可以更新 Model 資料, View 層 也可以更新 Model 資料. AngularJs 的1.x 版本是雙向資料流程的典型實現.

早在2009年, 雙向綁定是 Angualr 最受歡迎的特性之一, 但是 Angular 把這一特性拋棄了. 現在很多流行的框架和庫都使用了單向資料流程(React,Angular,Inferno,Redux等). 單向資料流程宣導的是清晰的架構, 資料流程動更加清晰和易管理. 對於單向資料流程來說說了點View自動更新資料的便利, 但也得到了清晰的資料流程.

JS框架中的變化偵測: 髒檢查, getter 和 setter, 虛擬 DOM

變化偵測對於現代 SPA應用來說很重要. 當使用者更新一些內容時, 應用必須以一種方法知道這種變化, 並做出反應更新.

AngularJS 1.x 使用的是髒檢查的方式, 具體做法是對View 中涉及到的 Model 進行深度比較. 髒檢查的優點在於它的簡單和可預測, 不涉及到 API 和物件的變更. 但是正因為涉及到大量比較, 也很低效.

Ember 和 Backbone 是使用getters 和 setters 來做變化偵測, 這樣涉及到資料修改時, 都會觸發變更事件. 而 React 是使用了虛擬 Dom 來做變化偵測, React 通過 setState方法來通知變更, 使用虛擬 Dom 來比較是否發生了資料變化.

Web Components元件

Web 元件是 Web 平臺上可複用的基礎組件, 而 Web Components 則定義了一些規範來實現這些可複用組件.

規範包括:

自訂元素

HTML Template

Shadow Dom

HTML imports 引入

Web Components 本身並不能代替 SPA框架的功能, 但是它的想法和核心概念, 在很多 SPA 框架中都有體現.

Smart 和 Dumb 元件

現在Web 的開發嚴重依賴元件, 而很多時候我們把元件分成 Smart 元件和 Dumb 元件.

Smart 元件, 又叫容器元件, 在元件內處理各種業務邏輯, 通常也管理 Dumb 元件,響應 Dumb 元件的事件.

Dumb 元件, 又叫展示組件, 通常被寫成純函數, 依賴於外部的資料和方法, 專注於展現資料.

JIT 編譯

Just-In-time(JIT)編譯指的是代碼的運行時, 被編譯成機器代碼的過程. 在JavaScript 運行時, JIT 能夠找到代碼的特定模式, 而這些模式可以讓 JavaScript 更快的被執行.

AOT 編譯

Ahead-Of-Time(AOT), 指的是編寫的代碼在運行之前, 被翻譯成機器代碼的過程. AOT 給 tree shaking 帶來了可能, 使用 AOT 預編譯, 對於生產環境下的代碼有以下好處:

更少的非同步請求, 範本和樣式內聯在 JS 內

更小的體積

更早的檢查到範本錯誤

更好的安全性

Tree Shaking

Tree Shaking 是指打包 JS 模組時, 通過對代碼的靜態分析, 排除掉不用的代碼的機制.

Tree Shaking 技術建立在 ES2015 模組的, import 和 export上, 支持我們導入特定的內容,而不是整個庫.

import { BehaviorSubject } from 'rxjs/BehaviorSubject';

這樣我們只導入了 BehaviorSubject, 而沒有導入整個 Rxjs 庫.

3 精讀

文中講到的現代 JavaScript 已經很多了, 再對理解的現代 JavaScript 補充幾條:

Dependent injection(依賴注入)

通過控制反轉,父級不需要關心子實現細節,將子類可能用到的實例都初始化好,由子類決定引入哪些依賴。還有一個好處是維持了單實例,這一點在資料流程中尤為重要,如果 store 不是單例的,那資料流程必然亂了套,既希望傳給子類使用,又要維持單例,依賴注入是很好的解決方案。

Symbol Reflect Proxy

Symbol 是 ES6中加入的一種新的資料類型, 每一個 Symbol 都是獨一無二的, 不與其它 Symbol 重複.

ES6中的 Proxy , 則是通過 Proxy 方法, 實現對於物件的一層攔截. 提供一種機制, 代理物件的操作. 而 Reflect 是一個內置的物件,它提供可攔截 JavaScript 操作的方法。方法與代理處理常式的方法相同。

這三篇文章非常詳細介紹了這三位 API:symbol, reflect, proxy

Server rendering

前端對後端渲染的熱度降了很多,主要是盲目跟風的氛圍消停了,真正需要的團隊已經穩定的用起來了。後端渲染的理念很新穎,一定程度説明了 html 認識到自己的不足,就像 Angular, React, Vue 對 webComponents 的衝擊一樣,或許未來十年可以用上 ECMAScript 標準提供的功能,但業務不能等待技術,現在唯有不斷折騰,直到被消滅或者招安。

4 總結

伴隨著各種框架的熱度, 理解這些現代 JavaScript 概念變得越來越重要, 大家可以以這個作為概覽, 詳細去學習和瞭解現代 JavaScript 的概念.

對於web前端的學習有不懂的,或者不知道學習路線,不知道學習方法,不知道該如何扎實能找到工作的朋友,我還是要推薦下我自己建的前端學習群:523218370,首先你要是前端黨,其次不管你是小白還是大牛,我都挺歡迎,小白嘛,主動點多問問題也就學好了,群裡每天分享乾貨,包括我自己最近花了一星期整理的一份適合2017年自學的最新web前端資料,送給大家,歡迎初學和進階中的小夥伴。

同類文章
Next Article
喜欢就按个赞吧!!!
点击关闭提示