範例
QuickJS 符合 ECMAScript 標準,因此支援 ECMAScript 規範的物件,像是 Object、Array、String…之類,請盡量操作這些物件的方法來寫程式。
這些資料很豐富,尤其是 Mozilla 寫的聖典《JavaScript Reference》,只要看這份文件,就能使用所有物件!
本文接下來只示範不屬於 ECMAScript 標準的功能…為什麼會需要另外增加標準外的功能?因為 ECMAScript 的 API,完全是以網頁瀏覽器的使用去制訂的,所以沒有主控台輸出入、檔案讀寫、檔案與資料夾增刪…等等與作業系統相關的功能。因此,做為直譯器,QuickJS 就必須彌補 ECMAScript 的不足,自行追加能讓程式設計師與作業系統互動的功能囉~
QuickJS 的官方文件只適合資深程式設計師閱讀,新手的話,網路資料不多且雜亂無章,所以本文彙整一些範例,一看就知道該怎麼做,希望能幫助到剛接觸 QuickJS 的人。
主控台輸出入
std.puts() 相當於 std.out.puts(),與 print() 不同之處在於結尾不會自動追加 '\n' 換行字元。
命令列參數
scriptArgs[0] 是 main.js。
scriptArgs 是 QuickJS 唯一一個全域變數。2
讀寫檔案、呼叫外部程式
更多 std.open() 所傳回 FILE 物件的操作方法
puts(str)
printf(fmt, ...args)
flush()
seek(offset, whence)
tell()
fileno()
read(buffer, position, length)
write(buffer, position, length)
getByte()
putByte(c)
os 模組的檔案讀寫
std 模組提供物件導向式的檔案讀寫功能,而 os 模組則提供程序導向式的檔案讀寫:
os.open(filename, flags, mode=0o666)
os.seek(fd, offset, whence)
os.write(fd, buffer, offset, length)
os.read(fd, buffer, offset, length)
os.close(fd)
不過,os.seek() 的位移量,依然是用 std 模組來存取:
std.SEEK_SET
std.SEEK_CUR
std.SEEK_END
取得檔案訊息
os.stat(path)
可以取得資料夾或檔案的訊息。
然而,這函式傳回的是 [obj, err] 陣列,所以必須先用索引值 0 取得表示訊息的物件,就能透過物件的 dev、ino、mode、nlink、uid、gid、rdev、blocks、atime、mtime、ctime
等屬性取得訊息:
CGI
自從 ECMAScript 6 引進能多行又能插值的 Backslash 字串,這語言變得很適合寫 CGI!
然而,別說 2020 年代了,不可能有人想寫 CGI,即使願意幹這種落伍的事,ECMAScript 一向都是實作在網頁瀏覽器裡,很少有好用的直譯器可以用在 CGI 上。
以嵌入到各裝置、各開發環境為訴求的 QuickJS,正好一拍即合!
當你臨時需要一個網頁伺服器,而且前端後端都想用 JavaScript 語言時,不妨拿支援 CGI 的 HTTP Server + QuickJS 來應急吧!雖然開發效率不高,難以滿足大型商務網站的需求,但寫寫動態網頁的話,會是令人愉快的組合。3
Web browser
POST 的話,使用 std.in.getline()
取得資料。
想把 QuickJS 的資料帶進 HTML 給 JavaScript 使用,只要變通一下,在 HTML 用 script 標籤宣告個變數,賦值為 QuickJS 的資料即可:
print(`<script>let save = '${std.loadFile('save.txt')}'</script>`);
這樣網頁瀏覽器的 JavaScript 就能透過 save 變數使用 QuickJS 的資料:
print(`<script>
if(save == 'Hello, world!'){
document.write('是在哈囉');
}
</script>`);
反過來要把 JavaScript 的資料傳給 QuickJS,也是變通一下,用 location.href 把 JavaScript 的資料放在 URL 的參數,傳給 CGI 的 QuickJS 使用:
let data = 'Hello, world!';
location.href = `save.cgi?data=${data}`;
要查看有哪些環境變數可用的話:
for(let n in std.getenviron()) print(n);
要列出所有環境變數內容的話:
for(let n in std.getenviron()) print(`${n} = ${std.getenv(n)}`);
其它好用的模組功能
std.printf(fmt, ...args) | 格式化輸出。 |
std.sprintf(fmt, ...args) | 格式化字串。 |
std.exit() | 結束程式。 |
std.gc() | 記憶體回收。 |
std.in | 對應 C 語言的 stdin 程式庫。 |
std.out | 對應 C 語言的 stdout 程式庫。 |
std.err | 對應 C 語言的 stderr 程式庫。 |
os.sleep(毫秒) | 暫停一段時間。 |
os.remove(filename) | 移除檔案。 |
os.rename(oldname, newname) | 修改檔案名稱。 |
os.mkdir(path, mode=0o777) | 建立資料夾 |
os.chdir(path) | 切換資料夾。 |
os.readdir(path) | 取得資料夾裡面的檔案清單,傳回 [str, err] 陣列。 |
os.utimes(path, atime, mtime) | 修改檔案時間。 |
os.kill(pid, sig) | 刪除行程。 |