這篇文章本來想跟「在Windows作業系統執行JavaScript程式」合併寫在一起,但是內容變得過長,自己也不知道怎麼讓主題明確,乾脆拆成兩篇來寫,讓這一篇可以專心把JavaScript模組化的功能寫清楚。
程式寫久了之後,就會開始思考如何模組化分析與設計(其實各行各業都是這樣),最大的用意就是可以重覆利用已經撰寫好的程式模組,提升開發效率。只是JavaScript程式語言原意是用來補強網頁只能靜態顯示的遺憾,並非將自身發展成完整的程式語言,因此在模組化功能並不特別強調(在網頁設計上是採用標籤來加入JavaScript程式)。
即使轉到WSH(Windows Script Host)的執行環境,JavaScript程式語言依然有此限制,所以想要進行模組化就要運用JavaScript的eval語法,讀入外部檔案後重新執行乙次來達到類似C語言的include()函數效果。但是在這篇「Windows Server System 系統管理之 Windows Script Host」介紹到WSF(Windows Script Files)架構,發現到其實可以藉由WSF架構來組織JavaScript程式,讓WSH(Windows Script Host)環境的JavaScript程式就具備include()函數的功能,而不再需要自行於程式中處理載入外部JavaScript程式。
底下將「在 Windows作業系統執行JavaScript程式」這篇文章中的共用函數獨立成一個檔案,分別寫出使用JavaScript的eval語法與WSF(Windows Script Files)的方式來載入外部程式。
先將共用函數getFolderList()獨立成JScript\FileUtils.js(置於JScript目錄下),程式碼如下:
/**
*
* 取得目錄內之檔案列表。
*
* @author ace
*
* @version 2010/11/11 v0.1
*
* @param {String} astrPath 搜尋路徑。
*
* @return {Array} 檔案列表。
*
* @requires Scripting.FileSystemObject
*
* @see JavaScript 程式設計
*
*/
function getFolderList(astrPath) {
var objReturn = new Array();
var objFSO = new ActiveXObject("Scripting.FileSystemObject");
var objFolder = objFSO.GetFolder(astrPath);
var objFilesEnum = new Enumerator(objFolder.Files);
var objSubFoldersEnum = new Enumerator(objFolder.SubFolders);
// 取得所有檔案。
while (objFilesEnum.atEnd() == false) {
objReturn.push(objFilesEnum.item());
objFilesEnum.moveNext();
}
// 取得所有目錄。
while (objSubFoldersEnum.atEnd() == false) {
objReturn.push(objSubFoldersEnum.item());
objSubFoldersEnum.moveNext();
}
return objReturn;
}
/**
*
* 取得檔案內容。
*
* @author ace
*
* @version 2010/11/11 v0.1
*
* @param {String} astrFile 檔案路徑。
*
* @returns {String} 檔案內容。
*
* @requires Scripting.FileSystemObject
*
* @see JavaScript 程式設計
*
*/
function getFileContent(astrFile) {
var strReturn = new String("");
var objFSO = new ActiveXObject('Scripting.FileSystemObject');
var objFile = objFSO.OpenTextFile(astrFile, 1, false, -1);
var strReturn = objFile.ReadAll();
objFile.Close();
return strReturn;
}
使用JavaScript的eval語法載入外部程式:
var objFSO = new ActiveXObject('Scripting.FileSystemObject');
var objFile = objFSO.OpenTextFile("JScript\\FileUtils.js", 1, false, 0);
eval(objFile.ReadAll()); // 載入外部JavaScript程式。
objFile.Close();
var objFileList = new Array();
objFileList = getFolderList("D:\\");
var strDisplay = new String("");
for (var intIndex = 0; intIndex < objFileList.length; intIndex++) strDisplay += objFileList[intIndex] + "\n";
WScript.Echo(strDisplay);
使用WSF(Windows Script Files)的方式:
<?xml version="1.0" standalone="yes" encoding="big5"?>
<package>
<job>
<script src="JScript/FileUtils.js" type="text/javascript" language="javascript" charset="utf-8"></script>
<script type="text/javascript" language="javascript" charset="utf-8">
<![CDATA[
var objFileList = new Array();
objFileList = getFolderList("D:\\");
var strDisplay = new String("");
for (var intIndex = 0; intIndex < objFileList.length; intIndex++) strDisplay += objFileList[intIndex] + "\n";
WScript.Echo(strDisplay);
]]>
</script>
</job>
</package>
以上兩種方式都可用來載入JScript/FileUtils.js檔案後執行對應的getFolderList()函數功能。從結構上看來,WSF(Windows Script Files)整體用法類似html,語法更加簡潔,也省去使用ActiveXObject自行讀入檔案的步驟。
最後則是補充一下測試上發現的狀況,WSF(Windows Script Files)檔案使用的是標準xml標籤語法,而且可以使用encoding屬性自行指定編碼格式,所以上述程式碼若將encoding屬性指定成"utf-8",就可以輸入"utf-8"編碼格式的字元。可是!!如果將外部JavaScript檔案使用"utf-8"編碼格式,使用<script>標籤載入時有可能發生不可預期的錯誤(也就是讀不出那些中文字)。
一開始測試時,滿腦子認為可以全部使用"utf-8"編碼格式之JavaScript檔案,結果遇到一些莫名其妙的錯誤,明明程式沒寫錯卻出現「程序呼叫或引數不正確」,真是見鬼了。還好有人分享同樣狀況的排除方法,請參考這篇「Microsoft VBScript 執行階段錯誤: 程序呼叫或引數不正確」,也才發現在WSH的環境下無法讀取"utf-8"編碼格式之JavaScript檔案。
最後總結一下,由於WSF(Windows Script Files)檔案可以使用"utf-8"編碼格式並執行,但是若是使用<script>標籤載入的JavaScript檔案只能使用"ANSI"編碼格式。為了避免混亂,只好統一採用ANSI編碼格式,所以才將WSF(Windows Script Files)檔案的encoding屬性定義成「<?xml version="1.0" standalone="yes" encoding="big5"?>」。因此若要運用WSF(Windows Script Files)架構來模組化JavaScript程式,需要注意編碼上的問題。
沒有留言:
張貼留言