以前知識星球有同窗問道了這樣一個問題:Node 環境和瀏覽器環境有什麼區別?這樣的思考很值得鼓勵,在對比中學習,很容易將一個抽象的知識具象化。當時的回答只是簡單的畫了個圖,感受有必要用此文來深刻挖掘一下javascript
想必沒有哪一個同窗不知道,Node 將 Js 擴展到了後端,雖然前端與後端在猿界是高頻詞彙,恐怕也未必能回答清楚什麼是前端,什麼是後端這個問題?前端
存在於每一個同窗的潛意識裏的答案:Web 前端指的是用戶看得見摸得着的東西,包括 UI 層面以及 Web 層面的交互實現;後端更多的是與數據庫進行交互以處理相應的,實現功能、數據的存取、平臺的穩定性以及性能等等java
我想說的是一個通訊層面上的區分, Web 應用基本上是基於 HTTP/HTTPS 構築的,前端(或者咱們延伸到大前端:Android、IOS、瀏覽器等多端)做爲 HTTP/HTTPS 的 Client 端,然後端則做爲協議的服務端node
結合上述兩點,能夠簡單的畫一個圖:數據庫
經過這個對比來服務於咱們對於 Node 的理解,運行在瀏覽器的 Js 主要是操做 Dom (UI 層面),以及做爲 HTTP 客戶端操做網絡通訊。而擴展到服務器端的 Node,能力再也不受瀏覽器沙盒的限制,能夠啓動 HTTP 服務(以及 WebSocket 等各類服務),能夠操做數據庫、輕鬆讀寫磁盤文件,等等等等後端
是時候祭出用來回答開篇提到的知識星球問題的圖了,在 Node 橫空出世以前,Js 的主要運行環境是瀏覽器(Android/IOS 中的 WebView 也是瀏覽器),瀏覽器主要由佈局引擎(也就是咱們經常說的瀏覽器內核)和Javascript 引擎組成,拿 Chrome 瀏覽器來講,它的佈局引擎是 WebKit(高版本的已經換成 Blink),佈局引擎的主要做用就是解析 Html Dom 和 Css 樣式規則;Javascript 引擎是 V8,顧名思義,Javascript 引擎的做用固然是編譯執行 javascriptapi
相比之下,Node 就不須要佈局引擎了,畢竟不須要渲染界面,因此在 Node 中是沒有 Window 對象的,由於它木有 Dom、Bom 的 api。注意到圖中左右皆有中間層,可是它們並不同,前者基於瀏覽器的沙盒,後者基於 libuv,在 IO 讀寫上的能力是不同的,例如:在 Node 上能夠輕鬆的讀寫磁盤文件,可是在瀏覽器中,麻煩到懷疑人生瀏覽器
至於 V8,已經超出了我能詳細講解的能力範圍,可是 V8 做爲一個開源的 Javascript 引擎,你能夠很方便在你的應用中調用,舉個栗子:bash
#include <v8.h>
using namespace v8;
int main(int argc, char *argv[]) {
// 建立一個句柄做用域 ( 在棧上 )
HandleScope handle_scope;
// 建立一個新的上下文對象
Persistent<Context> context = Context::New();
// 進入上一步建立的上下文,用於編譯執行 helloworld
Context::Scope context_scope(context);
// 建立一個字符串對象,值爲'Hello, Wrold!', 字符串對象被 JS 引擎
// 求值後,結果爲'Hello, World!'
Handle<String> source = String::New("'Hello' + ', World!'");
// 編譯字符串對象爲腳本對象
Handle<Script> script = Script::Compile(source);
// 執行腳本,獲取結果
Handle <Value> result = script->Run();
// 釋放上下文資源
context.Dispose();
// 轉換結果爲字符串
String::AsciiValue ascii(result);
printf("%s\n", *ascii);
return 0;
}複製代碼
能夠用一句話來歸納上述使用 C++ 編寫的 V8 調用實例:將 Js 代碼(字符串形式),丟到 V8 中執行並返回執行結果。這是最簡單的 V8 調用模板,要知道,Node 也是使用 C++ 基於 V8 寫出來的,經過這個例子,是否對 Node 有多一點點的認識呢?服務器
對 Java 有必定了解的同窗,對它的跨平臺特性確定耳熟能詳,這得益於它的虛擬機,什麼是虛擬機?這又能夠經過 Node 環境來幫助理解
Node 剛開始並無 Windows 版本,知道 2011 年 7 月,Node 在微軟的幫助下發布了 Windows 版本,從而實現了跨平臺。兼容 Windows 和 *nix 平臺主要得益於 Node 在操做系統與上層模塊之間構建了一層平臺架構層,也就是第三節中的中間層,也即 libuv。libuv 是許多系統實現跨平臺的基礎組件,感興趣能夠去了解下(具體的我也說不清楚了~~)
回到什麼是虛擬機的問題,莫不過是在系統於上層模塊之間架設的一套 IO 橋階層
不要給本身的知識領域設定邊界~~
菲麥前端 是一個讓知識深刻原理的知識社羣,咱們有 知識星球、公衆號以及羣,歡迎加微勾搭:facemagic2014