前端大牛程式設計師給你分享Web前端知識體系精簡—— javascript
Web前端 技術由 html、css和 javascript 三大部分構成,是一個龐大而複雜的技術體系,其複雜程度不低於任何一門後端語言。而我們在學習它的時候往往是先從某一個點切入,然後不斷地接觸和學習新的知識點,因此對於初學者很難理清楚整個體系的脈絡結構。本文將對Web前端知識體系進行簡單的梳理,對應的每個知識點點到為止,不作詳細介紹。目的是幫助大家審查自己的知識結構是否完善,如有遺漏或不正確的地方,希望共勉。

JAVASCRIPT 篇
0、基礎語法
Javascript 基礎語法包括:變數宣告、資料型別、函式、控制語句、內建物件等。
在ES5 中,變數宣告有兩種方式,分別是 var 和 function ,var
用於宣告普通的變數,接收任意型別,function用於宣告函式。另外,ES6 新增了 let、const、import 和 class
等四個命令,分別用以宣告 普通變數、靜態變數、模組 和 類 。
JS資料型別共有六種,分別是 String、Number、Boolean、Null、Undefined 和 Object 等, 另外,ES6新增了
Symbol 型別。其中,Object 是引用型別,其他的都是原始型別(Primitive Type)。
原始型別也稱為基本型別或簡單型別,因為其佔據空間固定,是簡單的資料段,為了便於提升變數查詢速度,將其儲存在棧(stack)中(按值訪問)。為了便於操作這類資料,ECMAScript
提供了 3 個 基本包裝型別 :Boolean、Number 和 String
。基本包裝型別是一種特殊的引用型別,每當讀取一個基本型別值的時候,JS內部就會建立一個對應的包裝物件,從而可以呼叫一些方法來操作這些資料。
引用型別由於其值的大小會改變,所以不能將其存放在棧中,否則會降低變數查詢速度,因此其儲存在堆(heap)中,儲存在變數處的值是一個指標,指向儲存物件的記憶體處(按址訪問),對於引用型別的值,可以為其新增屬性和方法,也可以改變和刪除其屬性和方法;但基本型別不可以新增屬性和方法。
Javascript 可以通過 typeof 來判斷原始資料型別,但不能判斷引用型別,要知道引用型別的具體型別,需要通過 Object 原型上的
toString 方法來判斷。
JS中的函式存在著三種角色:普通函式、建構函式、物件方法。同一個函式,呼叫方式不同,函式的作用不一樣,所扮演的角色也不一樣。直接呼叫時就是普通函式,通過new建立物件時就是建構函式,通過物件呼叫時就是方法。
JS常用的內建物件有window、Date、Array、JSON、RegExp
等,window是瀏覽器在執行指令碼時建立的一個全域性物件,主要描述瀏覽器視窗相關的屬性和狀態,這個後面會講到,Date 和 Array
使用場景最多,JSON主要用於物件的序列化和反序列化,還有一個作用就是實現物件的深拷貝。RegExp 即正則表示式,是處理字串的利器。

1、函式原型鏈
JS是一種基於物件的語言,但在ES6 之前是不支援繼承的,為了具備繼承的能力,Javascript 在 函式物件
上建立了原型物件prototype,並以函式物件為主線,從上至下,在JS內部構建了一條 原型鏈 。原型鏈把一個個獨立的物件聯絡在一起,Object
則是所有物件的祖宗, 任何物件所建立的原型鏈最終都指向了Object,並以 Object 終結。 ****
簡單來說就是建立了變數查詢機制,當訪問一個物件的屬性時,先查詢物件本身是否存在,如果不存在就去該物件所在的原型連上去找,直到Object物件為止,如果都沒有找到該屬性才會返回undefined。因此,我們可以通過原型鏈來實現JS繼承。
2、函式作用域
函式作用域就是變數在宣告它們的函式體以及這個函式體巢狀的任意函式體內都是有定義的。因此, JS中沒有塊級作用域,只有函式作用域
,這種設計導致JS中出現了 變數提升 的問題。簡單來說就是,將變數宣告提升到它所在作用域的最開始的部分,為了解決變數提升帶來的副作用,ES6新增了
let 命令來宣告變數,let 所宣告的變數只在 let 命令所在的程式碼塊內有效,所以不存在變數提升問題。
3、this 指標
this 指標存在於函式中,用以標識函式執行時所處的上下文。函式的型別不同,this指向規則也不一樣:對於普通函式,this
始終指向全域性物件window;對於建構函式,this則指向新建立的物件;對於方法,this指向呼叫該方法的物件。另外,Function物件也提供了call、apply
和 bind 等方法來改變函式的 this 指向,其中,call 和 apply 主動執行函式,bind一般在事件回撥中使用,而 call 和 apply
的區別只是引數的傳遞方式不同。
如果往深的去理解,無論什麼函式,this是否被改變, 本質上,this 均指向觸發函式執行時的那個物件。而在函式執行時,this 的值是不能被改變的。

4、new 操作符
函式的建立有三種方式,即 顯式宣告、匿名定義 和 new Function()
。前面提到,JS中的函式即可以是函式,也可以是方法,還可以是建構函式。當使用new來建立物件時,該函式就是建構函式,JS將新物件的原型鏈指向了建構函式的原型物件,於是就在新物件和函式物件之間建立了一條原型鏈,通過新物件可以訪問到函式物件原型prototype中的方法和屬性。
5、閉包
通俗來講,閉包是一個具有獨立作用域的靜態執行環境。和函式作用域不同的是,閉包的作用域是靜態的,可以永久儲存區域性資源,而函式作用域只存在於執行時,函式執行結束後立即銷燬。因此,閉包可以形成一個獨立的執行過程,關於閉包更
6、單執行緒和非同步佇列
Javascript
是單執行緒語言,在瀏覽器中,當JS程式碼被載入時,瀏覽器會為其分配一個主執行緒來執行任務(函式),主執行緒會形成一個全域性執行環境,執行環境在棧中採用後進先出(LIFO)的順序來執行程式碼塊,以保證所有的函式能按照正確的順序被執行。
但在瀏覽器中,有一些任務是非常耗時的,比如ajax請求、定時器、事件等,為了保證非耗時任務不受影響,Javascript
在執行環境中維護了一個非同步佇列(也叫工作執行緒),並將這些耗時任務放入佇列中進行等待,這些任務的執行時機並不確定,只有當主執行緒的任務執行完成以後,主執行緒才會去檢查非同步佇列中的任務是否需要開始執行。
JS中的 setTimeout 和 setInterval 就是典型的非同步操作,它們會被放入非同步佇列中等待,即使 setTimeout(0)
也不會被立即執行,需要等到當前同步任務結束後才會被執行。
想成為一個優秀的前端程式設計師碼?在這裡給那些:對於web前端的學習有不懂的,或者不知道學習路線,不知道學習方法,分享最新web前端資料,送給大家,獲取方式:【加企鵝裙】:九五六七六六六零四
學習路線:

7、非同步通訊 Ajax技術
Ajax是瀏覽器專門用來和伺服器進行互動的非同步通訊技術,其核心物件是XMLHttpRequest,通過該物件可以建立一個Ajax請求。Ajax請求是一個耗時的非同步操作,當請求發出以後,Ajax
提供了兩個狀態位來描述請求在不同階段的狀態,這兩個狀態位分別是 readyState 和 status ,readyState 通過
5個狀態碼來描述一個請求的5個階段:
0 - 請求未傳送,初始化階段
1 - 請求傳送中,伺服器還未收到請求
2 - 請求傳送成功,伺服器已收到請求
3 - 伺服器處理完成,開始響應請求,傳輸資料
4 - 客戶端收到請求,並完成了資料下載,生成了響應物件
status 用於描述服務端對請求處理的情況,200 表示正確響應了請求,404 表示伺服器找不到資源,500 代表伺服器內部異常等等。
Ajax物件還可以設定一個timeout 值,代表超時時間,切記:timeout 只會影響
readyState,而不會影響status,因為超時只會中斷資料傳輸,但不會影響伺服器的處理結果。 如果 timeout 設定的不合理,就會導致響應碼
status 是200,但 response裡卻沒有資料,這種情況就是伺服器正確響應了請求,但資料的下載被超時中斷了。
為了防止XSS攻擊,瀏覽器對Ajax請求做了限制,不允許Ajax 跨域請求伺服器,只允許請求和當前地址同域的伺服器資源。但不限制指令碼和標籤傳送跨域請求,比如
script 和 img 標籤,因此可以利用指令碼跨域能力來實現跨域請求,即JSONP 的原理。
JSONP雖然可以解決跨域問題,但只能是get請求,並且沒有有效的錯誤捕獲機制,為了解決這個問題,XMLHttpRequest Level2 提出了
CORS 模型,即 跨域資源共享, 它不是一個新的API,而是一個標準規範,當瀏覽器發現該請求需要跨域時,就會自動在頭資訊中新增一個 Origin
欄位,用以說明本次請求來自哪個源。伺服器根據這個值,決定是否同意這次請求。
隨著移動端的快速發展,Web技術的應用場景正在變得越來越複雜, 關注點分離 原則在系統設計層面就顯得越來越重要,而XMLHttpRequest 是
Ajax 最古老的一個介面,因而不太符合現代化的系統設計理念。因此,瀏覽器提供了一個新的 Ajax 介面,即 Fetch API ,Fetch
API 是基於Promise 思想設計的,更符合關注點分離原則。

8、模組化
歷史上,Javascript 規範一直沒有模組(module)體系,即無法將一個大程式拆分成互相依賴的小檔案,再用簡單的方法拼裝起來。在 ES6
之前,為了實現JS模組化程式設計,社群制定了一些模組載入方案,最主要有 CMD 和 AMD 兩種,分別以commonjs 和 requirejs為代表。ES6
在語言標準的層面上,實現了模組化程式設計,其設計思想是,儘量靜態化,使得編譯時就能確定模組的依賴關係,即編譯時載入,而CMD和AMD是在執行時確定依賴關係,即執行時載入。
9、Node.js
Node.js 是一個基於 Chrome V8 引擎的 JavaScript
執行環境,它的執行不依賴於瀏覽器作為宿主環境,而是和服務端程式一樣可以獨立的執行,這使得JS程式設計第一次從客戶端被帶到了服務端,Node.js在服務端的優勢是,它採用單執行緒和非同步I/O模型,實現了一個高併發、高效能的執行時環境。相比傳統的多執行緒模型,Node.js實現簡單,並且可以減少資源開銷。
10、ES6
ES6 是 ECMAScript 6.0
的簡寫,即Javascript語言的下一代標準,已經在2015年6月正式釋出了,它的目標是讓JS能夠方便的開發企業級大型應用程式,因此,ES6的一些規範正在逐漸向Java、C#等後端語言標準靠近。ES6
規範中,比較重大的變化有以下幾個方面:
新增 let、const 命令 來宣告變數,和var 相比,let
宣告的變數不存在變數提升問題,但沒有改變JS弱型別的特點,依然可以接受任意型別變數的宣告;const
宣告的變數不允許在後續邏輯中改變,提高了JS語法的嚴謹性。
新增解構賦值、rest語法、箭頭函式,這些都是為了讓程式碼看起來更簡潔,而包裝的語法糖。
新增模組化,這是JS走向規範比較重要的一步,讓前端更方便的實現工程化。
新增類和繼承的概念,配合模組化,JS也可以實現高複用、高擴充套件的系統架構。
新增模板字串功能,高效簡潔,結束拼接字串的時代。
新增Promise物件,解決非同步回撥多層巢狀的問題。
