JavaScript、jQuery、AJAX、JSON 這四個之間的關系?
http://www.zhihu.com/question/31305968
作者:艾拉斯
鏈接:http://www.zhihu.com/question/31305968/answer/116439739
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
1. JavaScript
JavaScript(簡稱js)是一種主要運行於瀏覽器中的弱類型的動態腳本語言,可以用來實現網頁上的一些高級功能,如數據驗證處理、頁面動態效果、定時任務、與用戶交互、發送/接收服務器端數據等等。
動態語言指的是程序運行時可以改變結構,主要體現在:
① js中的變量在聲明的時候不需要指定類型,其實際類型由程序運行中的賦值決定,在運行過程中變量的類型也可以改變。 注:這一點是動態語言的特征,並不是弱類型語言的特征,之前的回答有誤。
② 函數可變。js允許在運行過程中使用eval動態執行字符串里的命令,也可以通過new Function等方式由字符串動態構造函數,函數可以被創建、修改、刪除,可以從已有函數構造出新函數,等等。
③ 對象的成員可變,可以動態添加、刪除成員屬性或成員方法。
弱類型指的是js中的變量在參與運算的時候可以根據實際需要動態轉換類型。與之相對應的是強類型語言——變量一般不允許自動轉換類型(某些強類型語言的字符串連接操作除外),如果參與運算、調用時不符合要求的類型,則會在編譯階段報錯。
js是1995年由Netscape公司的Brendan Eich為自家的瀏覽器Netscape Navigator開發的,當時意圖是用於網頁上的表單驗證,即驗證表單的各個輸入項是否符合預定規則,在驗證通過后才向服務器提交表單內容,減少頁面與服務器端不必要的頻繁交互。
js的最初版本只用了10天就開發完成,當然不是完全從無到有,而是借鑒了其他一些語言的特性來開發。如此倉促開發,js自然有一些先天不足,但同時也具備了基於弱類型動態語言的方便靈活、對象原型繼承、函數是一種特殊的對象等優秀特性,於是越來越得到廣泛應用,而語言自身也在標准化組織的推動下不斷發展進步。
在瀏覽器發展的早期,Microsoft仿造JavaScript推出了相似的腳本語言JScript,在IE瀏覽器中使用,Microsoft同時推出的還有VBScript。后來為了解決不同瀏覽器中腳本語言不兼容的問題,在ECMA(歐洲計算機制造商協會)成立了標准化小組,由各廠商參與,共同制定JavaScript的語言規范,規范化的這門語言被命名為ECMAScript。
js也可以在瀏覽器之外的其他場合使用,如服務器端的Node.js、java的Rhino、無界面瀏覽器PhantomJS等。
2. jQuery
jQuery是js的一個工具庫,由John Resig在2006年發布。
j代表JavaScript,query是“查詢”的意思。也就是說,這個庫的意圖是基於JavaScript的查詢。
查詢的目標是什么?答案是DOM(文檔對象模型)結構中的Node(節點)。一個網頁就是一個html文檔,而網頁上的所有內容都是節點,包括文檔節點、元素節點、文本節點、注釋節點、屬性節點等等。而jQuery的查詢最主要針對的是元素節點,如段落(p)、錨點(a)、表格(table)等,只有少數方法可以處理文本節點與注釋節點。同時jQuery還可以用attr方法方便地對元素節點的屬性進行讀取/設置。
在jQuery出現之前,在js程序中獲取元素節點比較麻煩,例如獲取id為elem1的節點:
或者是獲取頁面上的所有checkbox元素,首先需要獲取input類型的元素:
然后對獲得的元素列表進行for循環處理,逐個判斷其類型是否為checkbox。
如果有更多元化的查詢要求,則對應的js代碼也會相當復雜。雖然有一些庫可以解決這方面的需求,但強大程度、易用性等方面都不太理想。
John Resig發現了一個盲點——css樣式應用到頁面上的元素時,是有一套規則的,即css選擇器,瀏覽器可以通過css選擇器找到匹配的元素並將指定的樣式應用到這些元素上。也就是說,通過css選擇器可以有效地進行元素查找定位,但它最初只被用於樣式領域。於是,John Resig根據css選擇器編寫了jQuery選擇器,並對選擇器的規則進行了擴充,從而讓元素查找變得非常方便。例如,上面2個例子用jQuery可以寫為:
與
同時,jQuery還有一個核心思想——鏈式操作,例如:
這樣的連續調用可以讓代碼書寫更加簡潔,也就是jQuery自己的口號:write less, do more。
此外,jQuery還提供了瀏覽器兼容、樣式讀寫、事件綁定與執行、動畫等特性,后來又加入了ajax、promise等,再加上方便的插件編寫機制,對整個js的生態圈產生了重大的影響,可以說是js歷史上影響力最大的一個庫。其中選擇器引擎后來被單獨剝離出來成為sizzle,供其他的js庫調用。這部分的工作還影響了官方,在jQuery成功之后,瀏覽器才有了querySelector與querySelectorAll方法。時至今日,雖然有了querySelector與querySelectorAll,但jQuery的選擇器仍然有少部分特性是前2者所無法替代的。
3. ajax
ajax全稱Asynchronous JavaScript and XML(異步的JavaScript與XML),是網頁無需刷新頁面、使用js與服務器進行交互的一種技術。
有時候會有這樣一種需求:只希望更改頁面上的一個區域。然而在從前的技術框架內只能刷新整個頁面,帶來的后果是:①需要重新傳輸整個頁面,服務器端與客戶端的流量消耗都會比較大;②如果是動態頁,服務器端需要重新生成整個頁面,即使是那些客戶原本不想要刷新的區域,增大了服務器的負擔。
Google的Jesse James Garrett在2005年初發表了一篇文章,提供了解決這種需求的技術方案,也就是ajax。實際上這是一種實踐先行的技術,該方案的技術依賴之一XMLHTTP在1998年就已經被Microsoft開發出來了,而Google在若干年后使用這項技術開發Google Maps等產品之后,才發表了相應的文章並對其進行了命名。
ajax的基本流程可以概括為:頁面上js腳本實例化一個XMLHttpRequest對象,設置好服務器端的url、必要的查詢參數、回調函數之后,向服務器發出請求,服務器在處理請求之后將處理結果返回給頁面,觸發事先綁定的回調函數。這樣,頁面腳本如果想要改變一個區域的內容,只需要通過ajax向服務器獲取與該區域有關的少量數據,在回調函數中將該區域的內容替換掉即可,不需要刷新整個頁面。
XMLHttpRequest在發送請求的時候,有兩種方式:同步與異步。同步方式是請求發出后,一直到收到服務器返回的數據為止,瀏覽器進程被阻塞,頁面上什么事也做不了。而異步方式則不會阻塞瀏覽器進程,在服務端返回數據並觸發回調函數之前,用戶依然可以在該頁面上進行其他操作。ajax的核心是異步方式,而同步方式只有在極其特殊的情況下才會被用到。
XMLHttpRequest在早期IE瀏覽器里是使用ActiveX來實現的,並不是瀏覽器自身的對象。后來其他各家瀏覽器也都實現了XMLHttpRequest對象,而高版本IE也把XMLHttpRequest改為了瀏覽器的內建對象。
4. JSON
JSON全稱JavaScript Object Notation(js對象標記法),由Douglas Crockford在2002年發現並制定了標准。從名稱上就可以看出來,JSON是基於JavaScript的,是JavaScript的一個子集。JSON是用JavaScript語法來表示數據的一種輕量級語言。
雖然Douglas在2002年就注冊了 http://json.org,並且為各種語言編寫了解析與構造JSON數據的庫,但在最開始的幾年JSON一直沒有得到足夠的重視。情況一直延續到ajax的出現。
從ajax的命名中我們就可以看到,數據交換是通過XML格式進行的。在ajax剛出現的時候,絕大多數應用都是采用XML格式,也有少數使用純文本的。但是XML格式有一個缺點,就是文檔構造復雜,需要傳輸比較多的字節數。在這種情況下,JSON的輕便性逐漸得到重視,后來替代XML成為ajax最主要的數據傳輸格式。可以舉個簡單的例子感受一下二者的區別:
XML規范實際上是比較復雜的,單純作為數據傳輸來說它太重了。在ajax領域中JSON取代XML的過程,是一個很好的“用腳投票”的范例。
而JSON的影響力在此后還繼續擴大,有些軟件將其作為配置文件的格式,有些編程語言也吸納了JSON的優點。例如c#,在高版本里可以這樣寫:
但是如果c# 2.0這樣寫,可是會報錯的。在2.0里只能寫成下面這種形式:
等價於
比較一下兩種寫法的區別,不僅有便捷性的差距,而且前一種寫法可以在聲明變量的同時為變量賦值,后一種寫法則不行,這會影響到類屬性的初始化操作:在c# 2.0中,只能把針對Dictionary之類復雜對象的初始化代碼寫在函數里,而不能直接寫在類屬性的聲明處。
感覺上是c#受了JSON(或者說js)的影響。但此處是我個人的感覺,如有錯誤請指出。
回到js自身,對於對象構造有兩種方法:基於對象的完整寫法,字面量表示法。前者如:
而與之對應的字面量表示法則寫為:
可以明顯看出字面量表示法要簡潔得多。而JSON基本就是字面量表示法的一個子集,除了強制要求鍵與字符串類型的值必須用雙引號包起之外,它剔除了undefined、function等類型,也不包括瀏覽器內置對象類型(如Date、RegExp等),是基於文本的、比較純粹的數據表示方法。所以說,Douglas是“發現”了JSON,而不是“發明”。標准的JSON不包含注釋,但后來因為實際需求而出現了能夠處理注釋的JSON庫。
5. Node.js
Node.js是Ryan Dahl在2009年發布的、主要用於服務器端的Javascript運行環境,也可以用於個人電腦。
Ryan Dahl此前一直在尋找一種事件驅動型的、異步的服務器端框架,實際上,js並不是他的首選。他是在嘗試了幾種語言之后,才發現js的函數回調與單線程特性正好契合他的要求,於是Node.js應運而生。
js的異步回調在ajax的部分已經提過:在調用異步方法的時候,可以將后續的處理函數作為參數傳入,在調用相應的異步接口之后,程序會將線程的控制權讓出,允許其他代碼執行;在接口返回處理結果后,再執行后續處理函數(即回調函數)。實際上,因為js是單線程語言,回調函數並不是立刻被執行的,而是會被送入任務隊列,在線程空閑、並且隊列前方沒有其他任務的情況下,才會被執行。
用戶在向服務器提交請求的時候,如果處理比較費時,傳統的服務器端框架會導致處理線程被阻塞。而js的特性使得異步任務在執行的時候讓出線程的控制權,在處理完成后再進行正確的回調,從而能夠獲得比較好的高並發處理能力。
js本身是一門嚴格的單線程語言,而Node.js為了充分發揮服務器的處理能力,在運行環境級別上增加了對於多線程的支持(child process)。但Node.js的多線程與常規的多線程有很大區別——常規語言的多線程允許多個線程共享數據,或者調用其他線程暴露出來的公開方法,而Node.js的多線程只能用消息機制進行通訊。這樣,Node.js就規避了常規多線程的數據同步、線程鎖(線程同步/互斥)等復雜問題,規避了一些潛在風險。
Node.js使用的V8引擎實際上就是Google的Chrome瀏覽器使用的Javascript引擎(因為V8引擎是開源的),並進行了模塊擴展。例如遵循CommonJS標准的模塊定義,適合服務器需求的多線程、集群、HTTP/HTTPS,文件系統,等等。Node.js中的很多方法都同時提供了異步版本與同步版本,從函數的命名上可以簡單區分。
得益於其模塊特性,Node.js的模塊擴展變得相當方便,用於Node.js包管理的npm得到了廣泛的使用,但也曾經引起“是否過度使用依賴包”的爭論。
Node.js不僅可用於服務器端,因為其安裝完成之后可以用命令行方式方便地調用,因此在個人電腦中也逐漸得到廣泛應用。例如為代碼編輯器提供插件、用於桌面的Node.js App等。另外還有一個重要的應用領域就是前端自動化,包括代碼的預編譯/轉換(如使用Babel將ECMAScript 6的代碼轉換為低版本的es代碼,將sass/less的樣式表文件編譯為傳統的css文件)、語法檢查、代碼文件或圖像文件的合並、代碼的混淆/壓縮、自動分發、自動測試等,還可以監視開發文件夾,在內容改變時自動執行上述操作,並自動刷新瀏覽器頁面。這樣使得前端領域的開發方式得到了大大進化。
js雖然因為有着一些先天不足而被人詬病,但這些年來卻越發展越壯大。這不僅僅是因為依托於瀏覽器這個宿主環境,更是因為其自身具備的一些優秀特性,Node.js的出現與發展就是一個很好的例證。
總結
ajax與Node.js都使用了js的異步回調特性。
jQuery的出現解決了那個各方面標准尚未統一的混亂時代的許多問題,讓js的應用更加廣泛,並為未來某些標准的制定指明了方向。
JSON從js中脫胎而出,作為一種簡潔、擴展性好的輕量級數據表示方法,在很多領域得到了廣泛使用。
Node.js在服務器端與開發流程中都越來越得到重視。
由於Node.js不包含BOM與DOM,因此jQuery不能直接在Node.js上使用,但可以借助jsdom、cheerio之類的庫,在構造出虛擬的dom結構后再使用。查看github上的jQuery開發包,可以看到它使用了Node.js上的grunt來進行自動化構建、測試的工作。
以上幾項技術的共同進步,配合瀏覽器的進步,此外還有硬件條件的發展,讓復雜的頁面應用越來越多,許多以前在服務器端進行的工作可以轉到客戶的瀏覽器中進行,順應了分布式處理的潮流。
鏈接:http://www.zhihu.com/question/31305968/answer/116439739
來源:知乎
著作權歸作者所有,轉載請聯系作者獲得授權。
1. JavaScript
JavaScript(簡稱js)是一種主要運行於瀏覽器中的弱類型的動態腳本語言,可以用來實現網頁上的一些高級功能,如數據驗證處理、頁面動態效果、定時任務、與用戶交互、發送/接收服務器端數據等等。
動態語言指的是程序運行時可以改變結構,主要體現在:
① js中的變量在聲明的時候不需要指定類型,其實際類型由程序運行中的賦值決定,在運行過程中變量的類型也可以改變。 注:這一點是動態語言的特征,並不是弱類型語言的特征,之前的回答有誤。
② 函數可變。js允許在運行過程中使用eval動態執行字符串里的命令,也可以通過new Function等方式由字符串動態構造函數,函數可以被創建、修改、刪除,可以從已有函數構造出新函數,等等。
③ 對象的成員可變,可以動態添加、刪除成員屬性或成員方法。
弱類型指的是js中的變量在參與運算的時候可以根據實際需要動態轉換類型。與之相對應的是強類型語言——變量一般不允許自動轉換類型(某些強類型語言的字符串連接操作除外),如果參與運算、調用時不符合要求的類型,則會在編譯階段報錯。
js是1995年由Netscape公司的Brendan Eich為自家的瀏覽器Netscape Navigator開發的,當時意圖是用於網頁上的表單驗證,即驗證表單的各個輸入項是否符合預定規則,在驗證通過后才向服務器提交表單內容,減少頁面與服務器端不必要的頻繁交互。
js的最初版本只用了10天就開發完成,當然不是完全從無到有,而是借鑒了其他一些語言的特性來開發。如此倉促開發,js自然有一些先天不足,但同時也具備了基於弱類型動態語言的方便靈活、對象原型繼承、函數是一種特殊的對象等優秀特性,於是越來越得到廣泛應用,而語言自身也在標准化組織的推動下不斷發展進步。
在瀏覽器發展的早期,Microsoft仿造JavaScript推出了相似的腳本語言JScript,在IE瀏覽器中使用,Microsoft同時推出的還有VBScript。后來為了解決不同瀏覽器中腳本語言不兼容的問題,在ECMA(歐洲計算機制造商協會)成立了標准化小組,由各廠商參與,共同制定JavaScript的語言規范,規范化的這門語言被命名為ECMAScript。
js也可以在瀏覽器之外的其他場合使用,如服務器端的Node.js、java的Rhino、無界面瀏覽器PhantomJS等。
2. jQuery
jQuery是js的一個工具庫,由John Resig在2006年發布。
j代表JavaScript,query是“查詢”的意思。也就是說,這個庫的意圖是基於JavaScript的查詢。
查詢的目標是什么?答案是DOM(文檔對象模型)結構中的Node(節點)。一個網頁就是一個html文檔,而網頁上的所有內容都是節點,包括文檔節點、元素節點、文本節點、注釋節點、屬性節點等等。而jQuery的查詢最主要針對的是元素節點,如段落(p)、錨點(a)、表格(table)等,只有少數方法可以處理文本節點與注釋節點。同時jQuery還可以用attr方法方便地對元素節點的屬性進行讀取/設置。
在jQuery出現之前,在js程序中獲取元素節點比較麻煩,例如獲取id為elem1的節點:
document.getElementById('elem1')
document.getElementsByTagName('input')
如果有更多元化的查詢要求,則對應的js代碼也會相當復雜。雖然有一些庫可以解決這方面的需求,但強大程度、易用性等方面都不太理想。
John Resig發現了一個盲點——css樣式應用到頁面上的元素時,是有一套規則的,即css選擇器,瀏覽器可以通過css選擇器找到匹配的元素並將指定的樣式應用到這些元素上。也就是說,通過css選擇器可以有效地進行元素查找定位,但它最初只被用於樣式領域。於是,John Resig根據css選擇器編寫了jQuery選擇器,並對選擇器的規則進行了擴充,從而讓元素查找變得非常方便。例如,上面2個例子用jQuery可以寫為:
$('#elem1')
$(":checkbox")
$('div.con') .height(100) .show();
此外,jQuery還提供了瀏覽器兼容、樣式讀寫、事件綁定與執行、動畫等特性,后來又加入了ajax、promise等,再加上方便的插件編寫機制,對整個js的生態圈產生了重大的影響,可以說是js歷史上影響力最大的一個庫。其中選擇器引擎后來被單獨剝離出來成為sizzle,供其他的js庫調用。這部分的工作還影響了官方,在jQuery成功之后,瀏覽器才有了querySelector與querySelectorAll方法。時至今日,雖然有了querySelector與querySelectorAll,但jQuery的選擇器仍然有少部分特性是前2者所無法替代的。
3. ajax
ajax全稱Asynchronous JavaScript and XML(異步的JavaScript與XML),是網頁無需刷新頁面、使用js與服務器進行交互的一種技術。
有時候會有這樣一種需求:只希望更改頁面上的一個區域。然而在從前的技術框架內只能刷新整個頁面,帶來的后果是:①需要重新傳輸整個頁面,服務器端與客戶端的流量消耗都會比較大;②如果是動態頁,服務器端需要重新生成整個頁面,即使是那些客戶原本不想要刷新的區域,增大了服務器的負擔。
Google的Jesse James Garrett在2005年初發表了一篇文章,提供了解決這種需求的技術方案,也就是ajax。實際上這是一種實踐先行的技術,該方案的技術依賴之一XMLHTTP在1998年就已經被Microsoft開發出來了,而Google在若干年后使用這項技術開發Google Maps等產品之后,才發表了相應的文章並對其進行了命名。
ajax的基本流程可以概括為:頁面上js腳本實例化一個XMLHttpRequest對象,設置好服務器端的url、必要的查詢參數、回調函數之后,向服務器發出請求,服務器在處理請求之后將處理結果返回給頁面,觸發事先綁定的回調函數。這樣,頁面腳本如果想要改變一個區域的內容,只需要通過ajax向服務器獲取與該區域有關的少量數據,在回調函數中將該區域的內容替換掉即可,不需要刷新整個頁面。
XMLHttpRequest在發送請求的時候,有兩種方式:同步與異步。同步方式是請求發出后,一直到收到服務器返回的數據為止,瀏覽器進程被阻塞,頁面上什么事也做不了。而異步方式則不會阻塞瀏覽器進程,在服務端返回數據並觸發回調函數之前,用戶依然可以在該頁面上進行其他操作。ajax的核心是異步方式,而同步方式只有在極其特殊的情況下才會被用到。
XMLHttpRequest在早期IE瀏覽器里是使用ActiveX來實現的,並不是瀏覽器自身的對象。后來其他各家瀏覽器也都實現了XMLHttpRequest對象,而高版本IE也把XMLHttpRequest改為了瀏覽器的內建對象。
4. JSON
JSON全稱JavaScript Object Notation(js對象標記法),由Douglas Crockford在2002年發現並制定了標准。從名稱上就可以看出來,JSON是基於JavaScript的,是JavaScript的一個子集。JSON是用JavaScript語法來表示數據的一種輕量級語言。
雖然Douglas在2002年就注冊了 http://json.org,並且為各種語言編寫了解析與構造JSON數據的庫,但在最開始的幾年JSON一直沒有得到足夠的重視。情況一直延續到ajax的出現。
從ajax的命名中我們就可以看到,數據交換是通過XML格式進行的。在ajax剛出現的時候,絕大多數應用都是采用XML格式,也有少數使用純文本的。但是XML格式有一個缺點,就是文檔構造復雜,需要傳輸比較多的字節數。在這種情況下,JSON的輕便性逐漸得到重視,后來替代XML成為ajax最主要的數據傳輸格式。可以舉個簡單的例子感受一下二者的區別:
<?xml version="1.0" encoding="utf-8"?> <root> <article> <title>Article Title1</title> <content>content1</content> </article> <article> <title>Article Title2</title> <content>content2</content> </article> </root>
{ "article" : [ { "title": "Article Title1", "content": "content1" }, { "title": "Article Title2", "content": "content2" } ] }
XML規范實際上是比較復雜的,單純作為數據傳輸來說它太重了。在ajax領域中JSON取代XML的過程,是一個很好的“用腳投票”的范例。
而JSON的影響力在此后還繼續擴大,有些軟件將其作為配置文件的格式,有些編程語言也吸納了JSON的優點。例如c#,在高版本里可以這樣寫:
Dictionary<int, string> dict = new Dictionary<int, string>{ {1, "a"}, {2, "b"} };
但是如果c# 2.0這樣寫,可是會報錯的。在2.0里只能寫成下面這種形式:
Dictionary<int, string> dict = new Dictionary<int, string>(); dict.Add(1, "a"); dict.Add(2, "b");
Dictionary<int, string> dict = new Dictionary<int, string>(); dict[1] = "a"; dict[2] = "b";
比較一下兩種寫法的區別,不僅有便捷性的差距,而且前一種寫法可以在聲明變量的同時為變量賦值,后一種寫法則不行,這會影響到類屬性的初始化操作:在c# 2.0中,只能把針對Dictionary之類復雜對象的初始化代碼寫在函數里,而不能直接寫在類屬性的聲明處。
感覺上是c#受了JSON(或者說js)的影響。但此處是我個人的感覺,如有錯誤請指出。
回到js自身,對於對象構造有兩種方法:基於對象的完整寫法,字面量表示法。前者如:
var obj = new Object(); obj.title = "title1"; obj.content = "content1";
var obj = { title: "title1", content: "content1" };
可以明顯看出字面量表示法要簡潔得多。而JSON基本就是字面量表示法的一個子集,除了強制要求鍵與字符串類型的值必須用雙引號包起之外,它剔除了undefined、function等類型,也不包括瀏覽器內置對象類型(如Date、RegExp等),是基於文本的、比較純粹的數據表示方法。所以說,Douglas是“發現”了JSON,而不是“發明”。標准的JSON不包含注釋,但后來因為實際需求而出現了能夠處理注釋的JSON庫。
5. Node.js
Node.js是Ryan Dahl在2009年發布的、主要用於服務器端的Javascript運行環境,也可以用於個人電腦。
Ryan Dahl此前一直在尋找一種事件驅動型的、異步的服務器端框架,實際上,js並不是他的首選。他是在嘗試了幾種語言之后,才發現js的函數回調與單線程特性正好契合他的要求,於是Node.js應運而生。
js的異步回調在ajax的部分已經提過:在調用異步方法的時候,可以將后續的處理函數作為參數傳入,在調用相應的異步接口之后,程序會將線程的控制權讓出,允許其他代碼執行;在接口返回處理結果后,再執行后續處理函數(即回調函數)。實際上,因為js是單線程語言,回調函數並不是立刻被執行的,而是會被送入任務隊列,在線程空閑、並且隊列前方沒有其他任務的情況下,才會被執行。
用戶在向服務器提交請求的時候,如果處理比較費時,傳統的服務器端框架會導致處理線程被阻塞。而js的特性使得異步任務在執行的時候讓出線程的控制權,在處理完成后再進行正確的回調,從而能夠獲得比較好的高並發處理能力。
js本身是一門嚴格的單線程語言,而Node.js為了充分發揮服務器的處理能力,在運行環境級別上增加了對於多線程的支持(child process)。但Node.js的多線程與常規的多線程有很大區別——常規語言的多線程允許多個線程共享數據,或者調用其他線程暴露出來的公開方法,而Node.js的多線程只能用消息機制進行通訊。這樣,Node.js就規避了常規多線程的數據同步、線程鎖(線程同步/互斥)等復雜問題,規避了一些潛在風險。
Node.js使用的V8引擎實際上就是Google的Chrome瀏覽器使用的Javascript引擎(因為V8引擎是開源的),並進行了模塊擴展。例如遵循CommonJS標准的模塊定義,適合服務器需求的多線程、集群、HTTP/HTTPS,文件系統,等等。Node.js中的很多方法都同時提供了異步版本與同步版本,從函數的命名上可以簡單區分。
得益於其模塊特性,Node.js的模塊擴展變得相當方便,用於Node.js包管理的npm得到了廣泛的使用,但也曾經引起“是否過度使用依賴包”的爭論。
Node.js不僅可用於服務器端,因為其安裝完成之后可以用命令行方式方便地調用,因此在個人電腦中也逐漸得到廣泛應用。例如為代碼編輯器提供插件、用於桌面的Node.js App等。另外還有一個重要的應用領域就是前端自動化,包括代碼的預編譯/轉換(如使用Babel將ECMAScript 6的代碼轉換為低版本的es代碼,將sass/less的樣式表文件編譯為傳統的css文件)、語法檢查、代碼文件或圖像文件的合並、代碼的混淆/壓縮、自動分發、自動測試等,還可以監視開發文件夾,在內容改變時自動執行上述操作,並自動刷新瀏覽器頁面。這樣使得前端領域的開發方式得到了大大進化。
js雖然因為有着一些先天不足而被人詬病,但這些年來卻越發展越壯大。這不僅僅是因為依托於瀏覽器這個宿主環境,更是因為其自身具備的一些優秀特性,Node.js的出現與發展就是一個很好的例證。
總結
ajax與Node.js都使用了js的異步回調特性。
jQuery的出現解決了那個各方面標准尚未統一的混亂時代的許多問題,讓js的應用更加廣泛,並為未來某些標准的制定指明了方向。
JSON從js中脫胎而出,作為一種簡潔、擴展性好的輕量級數據表示方法,在很多領域得到了廣泛使用。
Node.js在服務器端與開發流程中都越來越得到重視。
由於Node.js不包含BOM與DOM,因此jQuery不能直接在Node.js上使用,但可以借助jsdom、cheerio之類的庫,在構造出虛擬的dom結構后再使用。查看github上的jQuery開發包,可以看到它使用了Node.js上的grunt來進行自動化構建、測試的工作。
以上幾項技術的共同進步,配合瀏覽器的進步,此外還有硬件條件的發展,讓復雜的頁面應用越來越多,許多以前在服務器端進行的工作可以轉到客戶的瀏覽器中進行,順應了分布式處理的潮流。