使用VBScript和JScript編寫WEB應用程序
我心飛揚
寫這篇文章的動機是看到了大家對VBScript和Javascript的討論以及另一片類似的文章,覺得有必要將大家的想法加以整理:-),并將我在工作中產生的一些心得拿出來和大家分享,希望對大家有所幫助。當然,水平有限,錯誤在所難免。
Active Server Pages是Microsoft Windows DNA的重要組成部分,使用ASP我們可以很容易的構造功能強大的基于Web的應用。有很多腳本編寫語言可供我們進行ASP創作,如:VBScript、JavaScript、Perl 和Rexx等,你可以從幾種腳本編寫語言中選擇一個。本文中我們討論微軟公司所提供的兩種腳本編寫語言:
VBScript
JScript
首先,我想討論的是:
一、什么時候使用VBScript 和JScript,以及兩者之間的區別
VBScript 是Visual Basic的子集,全稱是Microsoft Visual Basic Scripting Edition。如果你曾經用過Visual Basic或者是Visual Basic for Applications (VBA),你就會覺得非常熟悉。不過它們并不完全一樣,因為VBScript是特意為在WEB中進行工作而設計的。
JScript是ECMAScript的Microsoft版本,是一組包括JScript 和JavaScript腳本編寫語言的標準定義。JScript從一組編程語言如C, C++, 以及Java等之中脫離出來的。如果你以前曾經用過C或者是Java,那么JScript的結構你會覺得非常熟悉。即便你不知道這些語言也沒有關系,JScript的結構一點也不難,它像C和Java一樣方便而沒有它們那么復雜。
微軟公司在Internet Explorer和Internet Information Server (IIS)中為它們提供了ActiveX Scripting Language(ActiveX腳本編輯語言)引擎(比如vbscript.dll、jscript.dll)。
那么,什么時候選擇何種語言?
我們知道,進行ASP開發無外乎要編寫下列兩種腳本之一:
1)服務器腳本:
在ASP頁面中為IIS編寫服務器腳本,無論使用那種語言都沒有問題。并且微軟公司的Visual InterDev對它們支持的都很好。
2)客戶端腳本:
如果你想在瀏覽器腳本中使用VBScript,那么瀏覽器必須是Internet Explorer的某個版本。因為其他瀏覽器可能不支持VBScript。如果要建立一個公共Web站點,你無法預知用戶使用的是什么瀏覽器,那么VBScript只能用于Internet Explorer這個限制就成問題了。
幾乎所有允許編寫腳本的瀏覽器都支持JScript。因此,如果為一個公共Web站點編寫應用程序,用JScript來編寫客戶端腳本是很自然的選擇。
影響你做決定的其他主要因素還有:
1、錯誤控制
在VBScript中有On Error 錯誤陷阱來對錯誤情況進行控制,如:On Error Resume Next。如果你編寫的是服務器腳本,錯誤控制非常重要,因為腳本的運行是無人照顧的。Jscript沒有這種機制。
2、格式化
VBScript有這樣的功能,能夠輕易地把數據,數字和貨幣數據格式化。JScript沒有這樣的功能。
3、動態執行
JScript一個非常有力的特性是:它允許你在你的腳本內動態地建立和執行腳本(eval()函數、execScript()方法等)。簡而言之,在你的腳本中能夠編寫腳本。當你用DHTML進行工作時,這個特性是非常有用的,因為這樣你就能夠動態的操作DHTML的文檔模型了。VBScript無此功能。例如,在客戶端的Javascript里你可以使用類似這樣的句法:
execScript("on error resume next:object.execWB 4, 1","VBScript");
4、面向對象
JScript使用的是一種基于原型的對象結構,允許你在腳本中定義對象。你能夠往對象的原型中加入方法和屬性,擴展內置對象和定制對象。例如:
//自定義對象myObject
function myObject(){
????//自定義屬性
????this.properties1=value;??//此時賦值為該屬性的默認值
????this.properties2;
????...
????//自定義方法
????this.myMethod1=Method1;
????this.myMethod2=Method2;
}
function Method1(arg){
????//block;
}
function Method2(arg){
????//block;
}
尤其有用的是該對象可通過SOM傳回客戶端,使得ASP編程方式更象以往的C/S結構。(我近期內可能會寫一篇深入討論SOM的文章,對該方法作詳細討論)
5、事件控制
用VBScript在Internet Explorer中控制事件很方便,就像在Visual Basic中一樣。在VBScript中也能夠建立一個隱含的事件處理程序,這只需要用對象事件結構形式來定義一項功能就行了,比如說隱式調用Button1_onclick。不過在Internet Explorer中,JScript沒有這項功能(但在其他的JScript主機上支持這項功能)。
在Internet Explorer 中使用JScript控制事件,會要求你鏈接到一個對象上,而這個對象又是與事件處理程序相連的。通常,只要在鑒別事件并且有處理程序功能的對象的標簽欄中指明其屬性即可。如下所示:
<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>
<!--
function button1_onclick() {
????alert("button1 Clicked")
}
//-->
</SCRIPT>
<INPUT type="button" value="Button" id=button1 name=button1 LANGUAGE=javascript onclick="return button1_onclick()">
或者使用類似下面的語法:
<SCRIPT ID=clientEventHandlersJS LANGUAGE=javascript>
<!--
function window_onload() {
????//Block;????
}
//-->
</SCRIPT>
<SCRIPT LANGUAGE=javascript FOR=window EVENT=onload>
<!--
window_onload()
//-->
</SCRIPT>
值得注意的是,上例中LANGUAGE屬性設置為“Javascript”。Internet Explorer對于"JScript" 和"Javascript"這兩個名字都認識,但許多其他瀏覽器卻只認識"Javascript",不認識"JScript" 。因此,為了保險起見,如果你不能確定該網頁是用Internet Explorer來瀏覽,就最好用"Javascript"。
6、數據類型
VBScript和JScript的數據類型差別比較大,JScript有6種數據類型:數值型、字符串型、對象型、
布爾型、null和undefined。VBScript雖然只有一種數據類型Variant,但其子類型比較豐富。特別
是其對數值類型的精細劃分使得在進行精確的數值運算時顯得比較放心。且配合第2條中所講到的
格式化功能使數據處理更加得心應手。有關這方面的文檔請參閱微軟的MSDN。
7、運算符
在運算符方面VBScript和JScript也有一些差別:
例如,VBScript增加了用于字符串連接的算術運算符“&”,用于對象比較的“is”運算符等。
然而JScript提供了比VBScript多得多的運算符,例如遞加遞減運算符“++、--”、一組位運算符
及typeof、delete等雜項運算符等。有關此方面的信息MSDN中非常詳細,在此不必復述。
8、字符串處理
VBScript和Javascript的字符串處理曾經也是網友們爭論的焦點,它們對字符串的處理有著本質
的不同,我之所以將這部分單獨提出來,也是想引發網友們作一些較為詳細的討論。
在VBScript中字符串只是一種簡單的數據類型而已,并為之提供了非常豐富的字符串處理函數,
例如:
ASC,Chr,InStr,InStrRev,Join,LCase,UCase,Left,Right,Len,LTrim,RTrim,Trim,Mid,Replace,
Space,String,Split,StrComp,StrReverse
因此有很大一部分網友認為VBScript的字符串處理功能比JScript簡捷、功能強大。
不過我不這么認為。簡捷是有可能的,但談到強大,我覺得JScript功能更為強大。在JScript中,
字符串不僅是一種數據類型,更是一類特殊的對象。作為對象的方法,他不僅提供了上述
VBScript中字符串函數的幾乎所有功能,而且配合正則表達式能夠提供更為強勁的功能。
一種典型的應用就是字符串的模糊搜索,看下面這個例子:
我想把一篇文章中的Chen0,Chen1,chenk,Chen99等可能的拼寫方法替換成JoyASP:
var txt = myTextFile.ReadAll();
var re = /chenk?\d?\d?/gi;
txt = txt.replace(re,"JoyASP");
這種用法在不能精確地預知被處理的字符串時顯得尤其有用。熟悉Unix,C,C++,Perl的網友可能
對正則表達式不會陌生,關于這方面的內容請查閱相關文章。
二、在同一個網頁中同時使用兩種語言
在同一個網頁中可以使用不同的腳本編寫語言。這樣做有以下幾個可能的原因:
A、在一個程序中充分利用各種語言的優點。
B、可能所面對的現有編碼是用你不熟悉的語言來編寫的。例如,DTC是用JScript編寫的,而
你熟悉的語言卻是VBScript。
大部分情況下,你可以在同一個網頁中混合幾種腳本語言并且它們相互之間能夠配合得很好。
用一種語言編寫的腳本可以調用用另外一種語言編寫的程序并且能夠共享全局變量。不過有時
候還是會出現一點小問題,現在就此說明一下。
1、當你從VBScript中調用一個JScript函數時,注意在調用過程中要有括號,即使這項函數不
要求設置參數也需如此。例如,一個調用應該像這樣:
returnValue = call_JScript_Function()
如果你忘記了加括號,那么這個函數所返回的值就不是你所希望的值,而是一個包含了函數本
身的VBScript無法解釋的對象。
2、服務器腳本的執行順序
被<% %>定界符括入的命令被稱為主腳本命令,主腳本命令按順序運行,從頭到尾。當然,你可
以在一個服務器腳本中定義一個可調用的程序(函數或者是子程序)。這樣的話,如果需要就
可以隨時調用它們。
所有的主腳本命令必須用同一種語言來編寫,也就是在網頁前面的<%@ LANGUAGE=xxxxx%>指示
中所指明的腳本語言。因此,在一個主腳本命令中你不能把幾種腳本語言混合起來。 你也許會
說“等一等”。在理論上,把服務器腳本放到<script>單元中是絕對可能的。就像下例一樣:
<%Response.Write("I Love joyASP!")%>
<SCRIPT language=VBScript RUNAT=Server>
Response.Write("I Love 我心飛揚, too.")
</SCRIPT>
但是,這樣你就會被IIS ASP處理程序的執行順序控制。例如,如果你建立了服務器腳本并且在
IIS 4.0中運行它,你會發現執行順序可能是這樣的:
1)非缺省語言的<SCRIPT>單元腳本
2)主腳本命令
3)缺省語言的<SCRIPT>單元腳本
以上的順序在很大程度上依賴于ActiveX腳本語言引擎的載入順序,同時IIS中的ASP處理程序可
能在將來會有所改變。因此,我不不大贊成按這種方式書寫代碼,建議你是只把<SCRIPT>單元
用于函數或者子程序,或是把它僅僅用于其他與執行順序無關的編碼。
3、客戶端腳本塊的順序
當你在客戶端把幾種語言混合使用時,<SCRIPT>塊在網頁中出現的順序非常重要,有時候會影
響到它們是否能正常工作。看看下面這個簡單的例子,它是在一個VBScript腳本中調用一個用
JScript編寫的函數:
<SCRIPT LANGUAGE="VBScript">
' 調用一個JScript function
her = "Lucy"
loveher = JSfuncLoveher(her)
document.write("絕密情報:" & loveher)
</SCRIPT>
<SCRIPT LANGUAGE="JavaScript">
function JSfuncLoveher(arg){
return "White、飛鳥和Moslem都想泡" + her + "MM :-)";
}
</SCRIPT>
它不會起任何作用。說得更明白一點,document.write()會往網頁中寫入一個空的字符串。為
什么?很簡單,在處理VBScript塊時,下面的Java Script <SCRIPT>塊還沒有被讀出來,沒有
進行語法分析,因此網頁不能使用它。當瀏覽器處理網頁中的腳本塊時,它是從上往下進行的。
在這個例子中,只需要調換一下腳本塊的順序就能夠解決這個問題了。不過,事實上這類問題
并不那么常見,在大多數情況下,<SCRIPT>中包含的函數和子程序只有當整個網頁被全部下載
下來并且所有的單元都可以使用之后才能夠被調用。不過,你還是要記住,網頁是按照一定的
順序來處理的,不同語言的<SCRIPT>塊是分別處理的。
3、區分大小寫以及命名習慣
JScript是嚴格區別大小寫的:在每個JScript的關鍵字,每個JScript命名空間的所有部分中,
你可以把大寫和小寫字母恰當的結合起來使用。這其中包括了你使用的對象模型中所有的關鍵
字。例如,當你使用ASP Response對象時,必須正確地使用大小寫字母(如Response.Write),
否則JScript會堅決不予承認。同樣,如果你為DHTML onclick事件編寫一個處理程序,如果用
在Visual Basic中經常發生的隨便使用大小寫的形式JScript可能就不會承認。
VBScript是不區分大寫和小寫字母的。在某種程度上,這種不計較大小寫的疏忽甚至在你用
VBScript對JScript編寫的單元進行訪問時都沒什么問題。下面例子中給出了兩個腳本。第一
個是用JScript編寫的,其中還包括了一個全局變量(ctr)和一個函數(doubleMe)。第二個
腳本是用VBScript編寫的,它是一個按鈕處理程序,它能夠調用JScript函數,并且報告全局
變量的值。
<SCRIPT LANGUAGE=javascript>
var ctr;
function doubleMe(aNumber){
????if(parseInt(ctr)){
????????ctr = ctr + 1;
????}
????else{
????????ctr = 1;
????}
return aNumber * 2;
}
</SCRIPT>
<SCRIPT LANGUAGE="vbscript">
Function btn1_onclick()
????numberToDouble = 12
????msgbox "The doubled number = " & DOUBLEME(numberToDouble)
????msgbox "You have doubled the number " & CTR & " times."
End function
</SCRIPT>
在VBScript腳本中,很明顯,我在提到doubleMe 函數和ctr變量時,沒有正確使用字母的大小
寫,但是程序依然運行良好。 這是一個好消息。而壞消息就是,在下面這些情況下你一定要注
意字母的大小寫:如果網頁中的JavaScript腳本所包含的單元只能夠通過字母的大寫和小寫來
區分,例如,一個叫做Timer()的函數和一個叫做timer的全局變量等等。很不幸,盡管這種編
碼方式不怎么好,但是有時候在你的網頁中還是可能會遇到原來就存在的編碼。
在一個函數調用中把JScript單元的名字作為一個字符串參數來使用
如果JScript包括的單元僅僅能夠用字母的大小寫來區分,那么VBScript就會把它們看成一樣的
(也就是說,不區分大寫和小寫)。VBScript只能看看不管大小寫的區別,它們是不是一樣,
因此它識別出的只有一個JScript單元。換一句話說,如果VBScript首先找到的是叫做Timer()
的函數,那么它就無法找到叫做timer的全局變量了,反之也是一樣。即便你在VBScript編碼中
十分注意的把它們做了區別結果也是一樣。因為VBScript在處理這些名字的時候認為它們只有一
種寫法。不幸的是,這里沒有其它的解決方法,除非在JScript的代碼中不利用這些大小寫之間
的微小差別來區分不同的函數名稱。
除了在某些特殊的情況下,把單元名作為參數使用這種問題并不常見。特殊情況之一是在Visual
InterDev 6.0中的腳本對象模型中。下面我會把它作為一個例子來使用,你可以把它看作是相同
情況下的處理準則。
Visual InterDev 6.0的腳本對象模型都是用JScript來編寫的。你也可以用VBScript來編寫自己
的編碼,它能夠與用VBScript區分大小寫方式編寫的腳本對象模型一起使用。有時候,你不能夠
直接調用某一方法,除非你把這個方法的名稱傳遞到一個JScript函數中,而由函數來調用這個
方法。
一個典型的例子就是警告方法,你可以用它把一個方法綁定到一個特殊的事件上。在下面這個例
子中,一個按鈕的onmouseover事件被綁定到changecaption()事件處理程序上。
<SCRIPT LANGUAGE="VBScript">
Function setAdviseMethods()
????Btn1.advise("onmouseover", "changecaption()")
End Function
</SCRIPT>
因為你把這些名字作為字符串傳送到一個JScript函數中,所以你必須使用正確的大小寫表示。
JScript會自動用它的區分大小寫的規則來檢查這些名字,如果大小寫不正確,就會找不到它們。
4、從VBScript 往JScript中傳送數組
有時候一個VBScript程序會傳送一個數組作為它的一個參數,或者作為它的返回值。你可以從JScript
中調用這個程序,不過必須把VBScript數組轉換成為一個可用的JScript數組。你只要在JScript函數中
建立一個VBArray對象并且用toArray把它轉換成為一個JScript數組就可以了。
注意:JScript不支持多維數組,如果原來的VBScript數組是多維的,經過toArray的轉換后它會成為一
個一維的JScript數組。 在下面的例子中有一個VBScript腳本,它建立了一個數組,還有一個JScript
腳本,它將說明如何才能獲得并使用這個數組:
<SCRIPT LANGUAGE="VBSCRIPT">
Function makeArrayVB()
????' 建立一個 VBScript 數組
????dim anArray(1,1)
????anArray(0,0) = "0,0"
????anArray(0,1) = "0,1"
????anArray(1,0) = "1,0"
????anArray(1,1) = "1,1"
????makeArrayVB = anArray
End Function
<SCRIPT LANGUAGE="JavaScript">
// 在 JScript 腳本中訪問 VBScript 數組
function getVBArray(){
????var arrayObj;
????var jsArray;
????arrayObj = makeArrayVB();
????jsArray = VBArray(arrayObj).toArray();
????alert("VBScript array length = " + jsArray.length);
????
????// 顯示數組的內容
????for(i=1;i<=jsArray.length;i++){
???????alert(jsArray[i-1]);
????}
}
</SCRIPT>
不過,在目前的VBScript(4.0)中,反過來是無法做到的。也就是說你不能把一個 JavaScript 數組轉換成
為VBScript數組。如果你非要在VBScript程序中使用JavaScript數組,你可以用下面的做法:
把JScript 數組轉換成一種不同的結構,如轉換成一個由分隔符限制的字符串等,這樣VBScript 就能夠使
用了。例如,你可以用 toString 函數把一個數組轉換成一個用逗號分隔的,無限制的字符串。這樣,在
VBScript 中你就能夠用 Split 函數把它分成不同的單元。很明顯這種方法在很多時候并不管用,不過有時
又的確有效。
以上羅里羅唆的寫了一大堆,希望能對網友們有幫助,也希望就某些問題展開討論。
最后,祝網友們 Happy Scripting!!