首頁  >  文章  >  web前端  >  從Java開發者的視角解釋JavaScript

從Java開發者的視角解釋JavaScript

伊谢尔伦
伊谢尔伦原創
2016-11-23 10:03:331375瀏覽

我們無法在一篇部落格文章裡解釋JavaScript的所有細節。如果你正或多或少地涉及了web應用程式開發,那麼,我們的Java工具和技術範圍報告揭示了,大多數(71%)Java開發者被歸到了這一類,只是你對JavaScript遇到了阻礙。

  毫無疑問,你已經知道了Java和JavaScript,不管它們有著多麼類似的命名,彼此沒有共享太多共同點。 Java的靜態型別、符合直接法則的簡單語法和冗長,與JavaScript的動態、缺乏一致性原則和怪異,有著巨大的差異。

  然而,JavaScript是web的程式語言,最近由於Node.js和JVM自己的Nashorn JavaScript引擎的發展,在伺服器端獲得了相當的注意。

  本文,我不想只是漫談JavaScript的好與不好,或重複任何人都能免費找到的、不計其數的JavaScript教程。我想列出一些有助於理解JavaScript做為一種語言的技術點,並從接近horse的角度來理解。

  我們將在本文包含下列語言層級的技術點:

JavaScript的通用性

JavaScript的函數程式設計問題

不同於Java的繼承

  另外,你會找到一些工具方面的推薦,沒有其他工具方面的推薦,沒有另外,你會找到一些工具方面的推薦,沒有其他工具,你是不想著手JavaScript專案的,包含了建構系統的程式碼品質分析和測試框架方面的工具。

  優點

  寫一次,差不多處處運作!

  毋庸置疑JavaScript是web程式語言,是許多其它語言的編譯目標,也是用來證明有時候人們只是想擁有更多自由時間的終極方式。儘管如此,這不是一件壞事。每一台能夠瀏覽現代網站的電腦都配備了具有效能和可用的JavaScript引擎。最重要的是,JavaScript程式碼可以在後端運行。

  內建於我們喜愛的JVM的、輕量級高效能JavaScript執行時間Nashorn,完全能夠解釋JavaScript腳本,也能夠解釋專案中帶有Java程式碼的JavaScript腳本。

  鑑於每台電腦運作時都可獲得的自由,JavaScript成為Java體驗的完美延續。

  函數式程式設計:一等公民是函數,而不是遞歸

  JavaScript中的函數是第一類公民,它們是值,可被儲存在變數中、傳遞給其它函數、在適當的時候再執行。

  這打開了函數式程式設計世界的大門,這是結構化JavaScript程式設計的完美方式。

  注意,JavaScript裡的物件是任何東西的映射,物件的每個特性(attribute)都在同一個映射裡:函數、屬性(property)、建構器;易變性帶來了更大的隱患,而對於Java,你至少能夠確保方法和欄位結構在某種程度上是穩定的。

  反過來,這使得函數式程式設計更加有利:涉及小的、可理解函數和不變的資料結構是在JavaScript裡運行的方式。

  這不是沒有依據的,以下是在JavaScript裡定義一個reduce函數的例子,來自於《Eloquent JavaScript》一書。

function forEach(array, action) {
for (var i = 0; i < array.length; i++) {
action(array[i]); //apply action to every element of the arra.
}
}
  
function reduce(combine, base, array) {
forEach(array, function (element) {
base = combine(base, element); // and here we apply function passed as ‘combine’ parameter to ‘base’ and ‘element’
});
return base;
}
  
function add(a, b) { // btw, this is how you define a function in JavaScript
return a + b;
}
  
function sum(numbers) {
return reduce(add, 0, numbers);
}

 注意:我們沒有在這裡使用reduce的遞歸版本。 JavaScript沒有以尾呼叫【註1】為特色,這表示每個函數的遞迴版本都會用到堆疊的深度,和Ja​​va一樣,如果你遞歸太深,程式就會崩潰。

  繼承:就像真實的世界

  JavaScript的繼承是基於原型的。即,你沒有擴展了其它類型的類型,而實際上,你擁有的實例從其它實例繼承了功能。

  想像一下,物件A就像一個映射,我們剛才稍微提到了一些、但是用了不同的視角,然後另一個類似映射的物件B從A繼承了一切。

 這說明B可以存取A所有部分:A的方法、欄位等等。

在實踐中,我從來沒有看到有人實際使用簡單的基於原型的繼承。通常當某人需要繼承時,他只是建構類,因此你可以用到所有廣泛的技能,和基於類別的繼承的工作模式。
——Rene Saarsoo,XRebel前端工程師

  我不太確定Java開發者應該從中吸取什麼,但是要當心繼承方式的不同,對於父級物件要格外留意、而不要意外地改變整個程式的行為。

  任何時候要避免的

  列出不可靠的JavaScript設計上的決定比想像中要容易。在JavaScript程式中要避免的最明顯的地方就是全域變數的宣告。

  注意,在JavaScript裡,無論什麼時候,不使用var關鍵字定義變量,那麼定義的變數被推到了它們被定義的作用域頂端。這意味著,每個用這種方式定義的變數將跑到全局範圍頂部,這會引發衝突以及你和同事不可預期的頭痛。

  可以開啟strict模式。只需在腳本檔案頂部寫上“use strict”,那麼不經意編寫的全域變數聲明將顯示錯誤。

  JavaScript與Java另一個重要的不同點在於,前者是動態型別語言,其真諦是所有東西都可以是任何型別。這很明顯了,實在不能再強調了:不要針對不同類型的值,去重複使用相同的變數。

  追蹤剛開始是個string類型的變量,但是現在它成了浮點數、或者函數了,相信我!

  還有,我不想太深入類型和布林值的討論,但是要警惕JavaScript引擎丟給你的隱式型別轉換。

  搞定工作的小提示

  正如我上面提到的,在程式設計上要更加註意這種語言的語法和怪癖,而不僅僅是知道。專案很少因為語言的不足而失敗,更多的失敗是與整體專案框架不足有關。以下是有助於你交付專案的一些工具。

  靜態程式碼分析

  大部分專案是不同的,其複雜度和需求導致了大量的細節,你該如何著手程式碼庫呢。儘管如此,在所有地方都有一致性的目標,那就是程式碼品質。

  是的,程式碼質量,對於任何開發者來說,最重要的工作就是交付。但不要在品質上妥協,不要對你提交的程式碼感到不自信就不情願與同事分享。

  幸運的是,JavaScript有一套得體的解決方案-JSHint。 JSHint是為JavaScript量身打造的靜態分析工具,與套用於Java程式碼的FindBug類似。 JSHint可以在你的程式碼庫運行,並且高亮出可疑的或有問題的地方,即使你不會馬上產生bug,但這些地方將來變得難以維護。在專案中支援它相當簡單。幫自己一個忙——如果你在寫JavaScript程式碼,就用JSHint讓它更安全、少一點尷尬。

  REPL

  REPL代表「讀取-求值-輸出」循環(Read-Eval-Print Loop)【註2】,是許多動態語言的強大工具。如果你看過Scala或Groovy,你一定能夠理解這個概念。

  啟動JavaScript REPL的一個方法是開啟瀏覽器的控制台,它產生了對JavaScript程式碼求值的介面。

從Java開發者的視角解釋JavaScript

 另一個比較方便的工具是jjs,它捆綁在JDK1.8。

從Java開發者的視角解釋JavaScript

它是命令列工具,允許你存取JDK中的Nashorn JavaScript 引擎,完全有能力執行那些甚至最為嚴格的JavaScript腳本。

  測試

  對於任何一個項目,你都想運行一些測試。測試對於動態類型的語言特別重要,最好選擇一種測試框架。我推薦Jasmine,它是用來測試JavaScript的行為驅動開發框架。

從Java開發者的視角解釋JavaScript

在Jasmine,你用describe描述測試套件,它阻止了你想測試的程式碼存取。在測試中的程式碼完成後,你expect一些結果。

  很明顯這裡不是要給出教程,但是我想讓你一瞥JavaScript程式碼看起來是多麼地優雅。 Jasmine是JavaScript專案最好的實踐之一,我們私下在產品開發中應用到了ZeroTurnaround項目,尤其是對於富含JavaScript的不間斷運行的交互分析器XRebel。

  建造工具

  最後,你的專案將需要的、比較重要的是建造工具。如果你在Java專案中使用JavaScript,請確保你可以避開Java建置工具,這就差不多夠了。但是,對於獨立的JavaScript項目,沒有必要引入龐然大物—Maven【註3】。

 可以考慮的JavaScript專案用到的建置工具是GulpJS【註4】。它是基於插件的建置系統,你可以為其指定任務。任務可以是「拷貝src目錄下的.js檔到dest」、或「壓縮我的JavaScript程式碼用於生產環境」。讓人受到震動的是,GulpJS把任務相關的文件流加入過濾器,因此你可以把上面的兩個任務加入一次有效的清掃中。

  還有大量的可用插件,借助適當的建造系統,你將發現專案中的協作會輕鬆很多。

  結論

  我們只是看到了JavaScript的冰山一角,並儘量介紹一些Java開發者在解決JavaScript時應該知道的概念和工具。自然地,這裡沒有提供要學習的完整的技術清單,但是如果你正準備義無反顧地深入JavaScript項目,這會幫助你起步,擁抱JavaScript的怪癖將有助於你不會頻繁地沮喪。

  你了解讓JS開發者走向快樂的秘密或最佳實踐嗎?毫無疑問我應該去分享!在下面評論或在Twitter:@shelajev上與我交談。我樂於聽到你的想法!

註1:在計算機科學裡,尾調用是指一個函數裡的最後一個動作是一個函數調用的情況:即這個調用的返回值直接被當前函數傳回的情況。這種情形下稱該呼叫位置為尾位置。若這個函數在尾位置呼叫本身(或是一個尾呼叫本身的其他函數等等),則稱這種情況為尾遞歸,是遞歸的一種特殊情形。尾調用不一定是遞歸調用,但是尾遞歸特別有用,也比較容易實現。 http://zh.wikipedia.org/wiki/尾呼叫

註2:REPL是一個簡單的,互動式的程式設計環境。這個字常用來指稱一個Lisp的互動式開發環境,但也能指涉命令列的模式和例如APL, BASIC, Clojure, F#, Haskell, J, Julia, Perl, PHP, Prolog, Python, R, Ruby, Scala, Smalltalk, Standard ML, Tcl, Javascript 這樣的程式語言所擁有的類似的程式設計環境。這也被稱為做互動式頂層構件(interactive toplevel)。 http://zh.wikipedia.org/wiki/%E8%AF%BB%E5%8F%96%EF%B9%A3%E6%B1%82%E5%80%BC%EF%B9%A3%E8 %BE%93%E5%87%BA%E5%BE%AA%E7%8E%AF

註3:Maven 除了以程式建置能力為特色之外,還提供Ant 所缺少的高階專案管理工具。由於 Maven 的缺省建置規則有較高的可重用性,所以常常用兩三行 Maven 建置腳本就可以建置簡單的項目,而使用 Ant 則需要十幾行。事實上,由於 Maven 的以專案為導向的方法,許多 Apache Jakarta 專案現在使用 Maven,而公司專案採用 Maven 的比例正在持續成長。 http://www.oschina.net/p/maven

註4:從頭編寫HTMLCSSJavascript是上個世紀的事情了,如今的JavaScript都是透過CoffeeScript這樣的支援句法縮寫的編輯器寫成的。如果你希望寫完JavaScript能夠一個工具完成程式碼清理優化工作,Gulp 就是你的不二之選,GulpJS類似Ant或Maven之於Java。 http://www.oschina.net/p/gulp

  原文:javascript-explain-it-like-im-a-java-developer 翻譯:labazhou


陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn