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