從Java開發者的視角解釋JavaScript

 咱們沒法在一篇博文裏解釋JavaScript的全部細節。若是你正或多或少地涉及了web應用程序開發,那麼,咱們的Java工具和技術範圍報告揭示了,大多數(71%)Java開發者被歸到了這一類,只是你對JavaScript遇到了阻礙。javascript

  毫無疑問,你已經知道了Java和JavaScript,無論它們有着多麼相似的命名,彼此沒有共享太多共通之處。Java的靜態類型、符合直接規律的簡單語法和冗長,與JavaScript的動態、缺少一致性原則和怪異,有着巨大的不一樣。html

  然而,JavaScript是web的編程語言,最近因爲Node.js和JVM本身的Nashorn JavaScript引擎的發展,在服務器端得到了至關的注意。前端

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

  咱們將在本文包含下列語言級別的技術點:git

  • JavaScript的通用性
  • JavaScript的函數編程問題
  • 不一樣於Java的繼承

  另外,你會找到一些工具方面的推薦,沒有這些工具,你是不想着手JavaScript項目的,包含了構建系統的代碼質量分析和測試框架方面的工具。github

  優勢

  編寫一次,差很少到處運行!

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

  內置到咱們喜好的JVM的、輕量級高性能JavaScript運行時Nashorn,徹底可以解釋JavaScript腳本,還可以解釋項目中帶有Java代碼的JavaScript腳本。編程

  鑑於每臺電腦運行時均可得到的自由,JavaScript成爲Java體驗的完美延續。gulp

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

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

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

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

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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】爲特點,這意味着每一個函數的遞歸版本都將用到棧的深度,和Java同樣,若是你遞歸太深,程序就崩潰。

  繼承:就像真實的世界

  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代碼求值的界面。

瀏覽器控制檯調試JavaScript

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

jjs的演示

  它是命令行工具,容許你訪問JDK中的Nashorn JavaScript 引擎,徹底有能力執行那些甚至最爲嚴格的JavaScript腳本。

  測試

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

Jasmine示例代碼

  在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:從頭編寫HTML\CSS\Javascript是上個世紀的事情了,現在的JavaScript都是經過CoffeeScript這樣的支持句法縮寫的編輯器寫成的。若是你但願寫完JavaScript可以一個工具完成代碼清理優化工做,Gulp 就是你的不二之選,GulpJS相似Ant或Maven之於Java。http://www.oschina.net/p/gulp

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

相關文章
相關標籤/搜索