聊聊JS語言是如何從前端移到後臺的

出處

js的出處大家都知道,先是netscape給自己瀏覽器寫的,後來標準化了,集成到ECMA標準集中,成爲ECMAScript 262標準,後來伴隨html5制定了265版本。
師出同門的還有flex 所用的action script, 和photoshop所用的腳本,最近還聽說有些硬件也用上了js。所以,大家今後其實還可以到這些領域去施展一下拳腳。

js起什麼作用?

js 首先是一種計算機語言,其最核心的功能是:

  1. 按邏輯執行程序
  2. 操控數據
  3. 輸入/輸出

其次纔是它的語法特性(比如OOP)、執行特性(比如異步)、易用性(比如自動內存管理)。
就其核心功能而言,js跟其它任何一門語言都無差別。

js的哪些特性是專爲瀏覽器設計的?

js在瀏覽器中的運行,運行環境上下文是由瀏覽器程序賦予的,即window對象。因此,瀏覽器中運行時,this即是指window。
js對瀏覽器的主要用途有二:

  1. 實現DOM標準。如構造及保存節點樹、提供訪問和操控方法、響應節點事件(mouseOver, click...)
  2. 與瀏覽器環境交互。如與窗口對象(Window)、Location、History、Navigator、Screen交互

上面第1點中的事件問題一定要注意。我也是直到今天才知道這是DOM標準的一部分,而javascript當初爲了實現這個標準,將響應事件的的能力內化在了語言中。也就成了後來大家所津津樂道的一大特性。其實,任何一種需要操控UI的語言都需要具備這種能力,或者通過別的方法變相實現這種能力(比如線程)。而那些不需要處理UI的語言就沒怎麼考慮過這個問題,如php, ruby, python, java,這些語言對事件的響應幾乎都是通過線程實現。但javascript是單線程的,無法啓動新線程,因此事件就成了變相多線程方式。

移植到瀏覽器以外的環境執行需要具備什麼條件?

我以前不知道瀏覽器有webkit和V8的時候,以爲瀏覽器是一個整體性的,不可分割的軟件。知道後,才發現原來瀏覽器內UI元素的管理和程序執行環境是分別由不同的引擎在支撐。
既然程序由專門的引擎(虛擬機)在支撐,那這個虛擬機就可以移出來。但是,脫離了瀏覽器的環境,移出來做什麼呢?
當然是做些常規程序做的事情:像perl一樣做系統管理腳本,或是像php/java那樣做服務器,或者像C一樣無所不能

  1. 但既然移出來到操作系統所提供的環境運行,那程序本身的存儲方式很大可能性就是文件,因此,操作文件的功能也必不可少。既然可以操作程序源文件或執行文件,那普通文件也自然不在話下,很多文件可以用來做爲數據源或存儲結果。
  2. 進一步考慮文件操作。文件如何讀入?讀入後如何存儲?無論是源代碼這樣的ASCII字符還是圖片、視頻、word文檔這種非ASCII數據,要讀進來,就需要具備Read()方法,存起來就需要Write()方法。而文件讀寫肯定不能一個字節一個字節的操作,所以,還需要有二進制數據的容器,Buffer就是幹這個的。考慮到不同的CPU和操作系統,以及網絡傳輸規範等情況,還需要對大端序和小端序的支持。
  3. 要做服務器,那就必須能夠打開一個網絡端口進行監聽。因此,網絡操作能力也需要具備,其實這也就是擴展一個跟操作系統間的接口而已。這在瀏覽器上也是可以的,但是沒必要。
  4. 進一步考慮網絡操作,網絡不能向磁盤一樣預先知道其確切的傳輸量。而是一個數據流,因此,需要一個流式的讀寫方法。
  5. js雖然是可響應事件的,但事件是爲DOM設計的,比如綁定對象必須是DOM節點(非HTML),事件會向父節點傳遞(冒泡)。對於更爲常規的編程,需要不一樣的事件機制,以及脫離DOM規範的設計。因此,需要實現一個額外的事件管理器。這就是NodeJs中的Event Class。
  6. 有時需要調用那些成熟軟件,就需要跟安裝在操作系統上的其它程序交互,通過在操作系統提供的shell環境,發起shell指令調用其它程序。這就是NodeJs中OS模塊的作用。

總結一下,需要移出來到操作系統的大環境中運行,需要以下特性:

  1. 文件操作
  2. 流式讀寫
  3. 二進制數據容器
  4. 網絡操作
  5. Event Class
  6. shell交互

如何操控DOM以外的對象?

  • 網絡:
  • 數據庫:
  • photoshop圖層:
  • 文件:
  • 二進制數據:
  • 聲音:
  • 串口:
  • USB設備:

總結:

無論哪種,它們都只是一個IO對象,這些對象都是二進制數據,或者是二進制數據驅動的。所以只要你能控制這些二進制數據,並能讀取或寫入到對應的地址或設備裏去,那就可以操控它。對js而言,涉及兩個問題:

  1. 二進制數據的操縱需要語言本身支持(其實幾乎所有語言都支持二進制數據的,但js本身恰恰並未支持,所以NodeJs一上來就先解決了這個問題);
  2. 地址和設備的讀寫控制由操作系統管理,所以要額外添加一些接口來跟操作系統溝通。這也是NodeJs需要一個標準庫的原因。

補充問題

  1. 標準庫沒涉及到的對象怎麼辦?比如遙控飛機、控制門鎖、藍牙通信、各類傳感器數據獲取等。這些設備的控制在標準庫中沒有,但屬於操作系統可控的範圍,因此,只要補充對應的操作庫即可。這就是NodeJs留有C++接口的原因。
  2. 那些操作系統管不了的事情怎麼辦?比如photoshop圖層、畫筆、flex中的元素、動畫等等。這些屬於應用層之上的對象,就需要應用自己創建一個執行環境,並賦予執行上下文,定義各類對象和執行邏輯。這樣就可以了。

跟其他語言有什麼異同?

從最底層的運行邏輯上講,js跟其它語言沒有什麼差異,都是以邏輯結構做爲執行條件。
從執行環境層面來說,各種語言的執行順序略有不同,有的語言是以順序運行,有的靠觸發,但根本上都是順序執行的,只是執行的範圍有所不同。因此,其執行是嚴格可預測的,而不能預測的只是事件發生的時間。

對JS應用的展望

js可以在瀏覽器上執行,也可以在服務器上執行,這是大家已經看到的。但其實它做爲一種常規語言,可以做幾乎任何事:

  • 做系統管理腳本。
  • 做普通GUI程序的控制語言。這需要擴展繪圖模塊,並在應用程序中集成js引擎。實際上現在linux上有個項目(Seed)就已經實現了,其圖形庫是GTK,控制語言使用javascript。
  • 做Android, ios平臺上的普通app。實際上現在的phoneGap(Cordova)就是將webkit+js引擎預先集成到app中,開發者僅需像開發web一樣開發即可。但這種app需要每個都集成一個webkit+v8(或其它js引擎)。更好的方式是整個大環境就是一個webkit+v8,然後每個app就只有相應的html, css, js代碼即可,firefoxOS既是如此。要做手機app,則需要js引擎補充實現各種設備訪問接口。如撥號、3D傳感器、攝像頭、GPS、藍牙等。
  • 在帶操作系統的微型PC上運行。比如前面帖子中有人編譯到了openWRT上;還有一個控制auduino的NodeJs模塊(名叫Johnny-Five)
  • 其它IO密集,但處理時效性要求高的領域裏
  • 但也有例外,js也有不能做的事情:
    1. 單片機程序,或者實現一個裸機操作系統。因爲js必須要一個虛擬機來運行,而虛擬機本身還不具備操作系統的功能。如設備管理、內存管理(這裏可不是指自動垃圾回收機制,而是真正的物理內存)、任務調度(當然,單一功能的設備上,單線程的js無需理會這個需求)。
    2. 科學計算。(這個不知道我說的對不對,求指正)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章