在安裝完 JDK8,並設定好 PATH 中包括 JDK 的 bin 目錄之後,我們來寫每個程式語言都會練習的第一個程式 “Hello, World”,首先,請新增一個純文字檔案,將檔案名稱改為 hello.js(別忘了你要看得到副檔名),然後編輯檔案內容:
print('Hello, World');
看!第一個 Java 程式就是這麼簡單,接著開啟命令列,切換到 hello.js 所在目錄,使用 jjs 指令來執行程式:
> jjs hello.js
Hello, World
(這不是 Java 啊!啊!啊!啊!… XD)
被識破了嗎??JDK8 包括了一個新的 JavaScript 引擎 Nashorn,你可以使用命令列工具 jjs 來運行 JavaScript 程式,這包括在 JDK 的 bin 目錄中,你也可以在 Java 程式中嵌入 Nashorn 引擎。
這篇文章,要先來談談,命令列工具 jjs 可以如何執行 JavaScript 程式。你可以直接鍵入互動模式,測試一些簡單的 JavaScript:
>jjs
jjs> print('Hello, World')
Hello, World
jjs> 1 + 2
3
jjs> [1, 2, 3].join(', ')
1, 2, 3
jjs> exit()
如果要在目前 .js 檔案中,載入其他 .js 檔案,可以使用 load,可以是本機或是遠端主機上的檔案。例如:
load('https://openhome.cc/Gossip/JavaScript/samples/js/gossip-0.1.js');
XD.each(['a', 'b', 'c'], function(elem) {
print(elem);
});
嚴格模式
Nashorn 引擎是基於 ECMAScript 5.1,未來的 Nashorn 版本可望支援 ECMAScript 6,因而基本上,在〈JavaScript 語言核心〉 系列中介紹到 ECMAScript 5,Nashorn 都可以支援,像是 嚴格模式,你也可以在執行 jjs 指令時加上 -strict 表示使用一律嚴格模式(預設不啟用嚴格模式),而不用在程式碼中使用 'use strict' 字串。
例如,如果你有個 hello.js 如下:
name = 'Justin';
print('Hello, ' + name);
如下執行時就會發生錯誤,因為 ECMAScript 5 嚴格模式下,變數必須使用 var 宣告:
>jjs -strict hello.js
hello.js:1 ReferenceError: "name" is not defined
scripting 模式
執行 jjs 指令時如果加上 -scripting,可以使用 Nashorn 本身提供(而 JavaScript 本身沒有)的一些特性。
例如,JavaScript 本身對 '' 或 "" 來建立字串並沒有區別,如果加上了 -scripting,"" 包括的字串中若有 ${expr},expr 將會被執行,'' 則不會做任何處理。例如:
var name = 'Justin';
print('Hello, ${name}');
print("Hello, ${name}");
print("Hello, ${name.toUpperCase()}");
執行結果如下:
>jjs -scripting hello.js
Hello, ${name}
Hello, Justin
Hello, JUSTIN
scripting 模式下,多了一些全域變數可以使用,例如,可以使用 $ARG 取得命令列引數:
$ARG.forEach(function(elem, index) {
print("index: ${index}, elem: ${elem}");
});
指定命令列引數時,除了加上 -scripting 外,命令列引數必須銜接在 -- 之後。例如:
>jjs -scripting hello.js -- 1 2 3
index: 0, elem: 1
index: 1, elem: 2
index: 2, elem: 3
在不使用 -scripting 的情況下,也可以使用 arguments 來取得命令列引數。
在加上 -scripting 的情況下,$ENV 可用來取得一些環境變數。例如:
for(var prop in $ENV) {
print("${prop}: ${$ENV[prop]}");
}
以下是一個執行範例與結果顯示片段:
>jjs -scripting hello.js
USERDOMAIN_ROAMINGPROFILE: Justin-2012
LOCALAPPDATA: C:\Users\Justin\AppData\Local
PROCESSOR_LEVEL: 6
FP_NO_HOST_CHECK: NO
USERDOMAIN: Justin-2012
LOGONSERVER: \\JUSTIN-2012
PROMPT: $P$G
SESSIONNAME: Console
略...
如果想執行外部指令,可以使用 $EXEC,例如,$EXEC('notepad') 將會開啟記事本。如果你不喜歡使用 print,那在 -script 下可以使用 echo 代替,如果想提示訊息並取得使用者輸入,可以使用 readLine 方法,使用 readFully 則可以取得檔案內容:
var fileName = readLine('Input a filename: ');
var content = readFully(fileName);
echo(content);
執行結果範例如下:
>jjs -scripting hello.js
Input a filename: hello.js
var fileName = readLine('Input a filename: ');
var content = readFully(fileName);
echo(content);
-scripting 模式下,可以使用 # 作為註解,如果 # 出現在原始碼的第一行,不用加上 -scripting,也會自動進入 scripting 模式。
scripting 模式下,可以撰寫 HereDoc,也就是多行字串,直接來看個範例就知道怎麼撰寫:
#
var doc = <<DOC
Hello, ${arguments[0]}.
This is heredoc example.
Try it!
DOC
print(doc);
<< 表示開始一個 HereDoc,DOC 指定了一個識別名稱,作為多行字串結束標記,標記名稱可以自訂,HereDoc 中可以直譯字串。一個執行結果如下:
>jjs hello.js -- Justin
Hello, Justin.
This is heredoc example.
Try it!
更多 Nashorn 的 scripting 模式說明,還可以參考〈Nashorn and Shell Scripting〉。
jjs 是為 Nashorn 量身打造的指令,如果想與 JSR223 相容,可以使用 jrunscript,詳情可察看〈Invoking Nashorn from the Command Line〉。

