這篇文章本來想跟「在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程式,需要注意編碼上的問題。
沒有留言:
張貼留言