VBS與JS變量共享與互操作


<Job id="VBS_JS_CallEachOther_Test">
<comment id="note.all">
1.支持跨語言的變量、函數、過程;
1.1VBS所有的數字類型自動轉換為JS的Number類型;
1.2VBS數組,在JS中自動包裝為VBArray對象,類型為unknown;可用其toArray方法轉換為JS的數組
1.3VBS類型=>JS類型:
   Byte/Integer/Long/Single/Double/Currency/Decimal=>Number;
   Array=>unknown;Nothing/Null/COMObject=>Object;Date=>Date;
1.4JS類型=>VBS類型:
   null=>Null;NaN=>Double;Number(整數)=>Long;Number(浮點數)=>Double;
   Array/Date/Error/Object/Function/RegExp/ClassObject=>JScriptTypeInfo
   COMObject=>COMObject[如new ActiveXObject('Scripting.FileSystemObject')=>FileSystemObject]
1.5VBS類型<=>JS類型:
   Boolean<=>Boolean;String<=>String;Empty<=>undefined
1.6VBS的Date類型,共享到JS中也是Date類型,但是在JS中無法按照原生的JS Date對象一樣對其進行操作
2.不支持跨語言類,但支持跨語言類對象變量
3.所有的由JS代碼中定義后轉換到VBS中的JScriptTypeInfo類型變量,都可以原樣訪問在JS中定義的
  屬性/方法
4.JS數組共享到VBS中表現為JScriptTypeInfo類型,但無法簡易地對其進行元素讀寫操作,要進行此類操作
  請先將它轉換成VBS的數組后,再對新數組進行讀寫
5.VB6/VBA中借助MSScriptControl,與JS數據結構進行互操作的規則,與這里的VBS大同小異;VB6/VBA中有
  CallByName函數,可以通過如CallByName(js_arr,"0",vbGet)這樣的形式來直接讀取數組元素;修改元素
  則是使用CallByName(js_arr,"0",vbLet/vbSet,newValue);VB6/VBA中JScriptTypeInfo類型變量的一切
  操作都只能通過CallByName來進行,這方面比VBS麻煩 </comment> <script id="global" language="JScript"> var alert=function(){ var result=''; for(var i=0;i<arguments.length;i++) result=result+arguments[i]+', '; WScript.Echo(result.slice(0,-2)); } </script> <script id="vbs.test" language="VBScript"> Dim vbs_arr,vbs_int,vbs_single,vbs_str Dim vbs_bool,vbs_empty,vbs_circle,vbs_date Dim vbs_err vbs_arr=Array(1,2,3) vbs_int=3 vbs_single=3.25 vbs_str="vbs_str" vbs_bool=True vbs_empty=Empty Function vbs_func(a,b) vbs_func=a+b End Function Sub vbs_sub(a,b) alert typename(a),typename(b) End Sub Class Circle Private D_ Public D_History Public Property Get D() D=D_ End Property Public Property Let D(Value) D_=Value D_History=D_History & Value & ", " End Property Public Function GetArea() GetArea=4*Atn(1)*Me.D^2 end function Private Sub Class_Initialize WScript.Echo "Circle Object Initialized!!!" End Sub Private Sub Class_Terminate WScript.Echo "Circle Object Terminated!!!" End Sub End Class Set vbs_circle=New Circle vbs_date=Now on error resume next err.raise 6 '溢出錯誤 'set vbs_err=new ErrObject '用Err/ErrObject/Error都無法創建VBS的錯誤對象 set vbs_err=Err 'err.Clear 'vbs_err與err是同一個對象,所以為后面的試驗,這里最好注銷 </script> <script id="js.test" language="JScript"> var js_arr=[1,2,3]; var js_int=3,js_single=3.2,js_double=3.2324242432424; function js_func(a,b){ alert(typeof a,typeof b); } var js_str='hello world'; var js_bool=true; var js_undefined=undefined; function Square(Length){ this.Length=Length; this.GetArea=function(){ return this.Length*this.Length; } } var js_square=new Square(5); var js_date=new Date(); var js_err=new Error(146250,'what the fuck are you doing?'); </script> <script id="js.main" language="JScript"> (function JS_VBS_TEST(){ //1.同一個域里面的VBS數組在JS代碼塊中是可見的,其類型是unknow, // 實際是VBArray,可使用VBArray.toArray()將其轉換為JS數組 alert("typeof vbs_arr",typeof vbs_arr); alert("vbs_arr.toArray()",vbs_arr.toArray()); //2.同一個域里面的VBS數字類型的變量在JS代碼塊中也是可見的,其 // 類型一律是number alert("typeof vbs_int",typeof vbs_int); alert("vbs_int",vbs_int); alert("typeof vbs_single",typeof vbs_single); alert("vbs_single",vbs_single); //3.同一個域里面的VBS函數/過程在JS代碼塊中也是可見的,其類型 // 一律是unknown,無法直接轉換為JS函數,但是可以直接調用;無 // 法以apply的方式來調用; alert("typeof vbs_func",typeof vbs_func); alert("vbs_func(3,6)",vbs_func(3,6)); //alert("vbs_func.apply(undefined,[3,6])",vbs_func.apply(undefined,[3,6])); alert("typeof vbs_sub",typeof vbs_sub); alert("vbs_sub(3,undefined)",vbs_sub(3,undefined)); alert("vbs_sub([1,2],/\w+/g)",vbs_sub([1,2],/\w+/g)); alert("vbs_sub(3.7293,null)",vbs_sub(3.7293,null)); alert("vbs_sub(new Date(),NaN)",vbs_sub(new Date(),NaN)); alert("vbs_sub('hello',true)",vbs_sub("hello",true)); alert("vbs_sub(new Error(3),3.56790456909656789)", vbs_sub(new Error(3),3.56790456909656789)); alert("vbs_sub({},function add(){})",vbs_sub({},function add(){})); alert("vbs_sub(new Object(),new Square())",vbs_sub(new Object(),new Square())); alert("vbs_sub(Math,new ActiveXObject('Scripting.FileSystemObject'))", vbs_sub(Math,new ActiveXObject('Scripting.FileSystemObject'))); //4.同一個域里面的VBS字符串類型的變量在JS代碼塊中也是可見的,其 // 類型是string,與JS字符串是互通的,JS的字符串方法都可以直接用 alert("typeof vbs_str",typeof vbs_str); alert("vbs_str",vbs_str); alert("vbs_str.toUpperCase()",vbs_str.toUpperCase()); //5.同一個域里面的VBS布爾類型的變量在JS代碼塊中也是可見的,其 // 類型是boolean,與JS的布爾類型是互通的 alert("typeof vbs_bool",typeof vbs_bool); alert("vbs_bool",vbs_bool); //6.同一個域里面的Empty類型的變量在JS代碼塊中也是可見的,其 // 類型是undefined,與JS的Undefined類型是互通的,調用VBS函數/過程 // 時在JS中傳入undefined,在VBS函數/過程中接受到的將是Empty alert("typeof vbs_empty",typeof vbs_empty); alert("vbs_empty",vbs_empty); alert("vbs_func(3,6)",vbs_func(3,6)); //7.同一個域里面的類類型的變量在JS代碼塊中也是可見的,其類型是 // object,其方法/屬性都可以正常訪問,但是無法實現apply式調用;其公共的 // 方法屬性可以使用for...in完成遍歷,這些遍歷到的索引可以用來進行 // 成員訪問,其可訪問方法的類型如一般的函數一樣是unknown類型,所以 // 如果只是想要遍歷屬性和方法中的一者,就可以使用這個類型判定,來 // 獲取對應的成員名列表 vbs_circle.D=10 alert(vbs_circle.D) alert("typeof vbs_circle",typeof vbs_circle); //object alert("vbs_circle.GetArea()",vbs_circle.GetArea()); //alert(vbs_circle.GetArea.apply(vbs_circle)); alert('for...in: '); for(var i in vbs_circle) if(typeof vbs_circle[i]=='unknown') alert('vbs_circle.'+i+'(...) = '+vbs_circle[i]()); else alert('vbs_circle.'+i+' = '+vbs_circle[i]); alert('read/write by property/method index: '); alert("vbs_circle['D'] = "+vbs_circle['D']); alert("vbs_circle['D_History'] = "+vbs_circle['D_History']); alert("vbs_circle['GetArea']() = "+vbs_circle['GetArea']()); alert("typeof vbs_circle['D']",typeof vbs_circle['D']); //number alert("typeof vbs_circle['D_History']",typeof vbs_circle['D_History']); //string alert("typeof vbs_circle['GetArea']",typeof vbs_circle['GetArea']); //unknown //var vc=new Circle(); //報錯 //alert(typeof vc); //undefined vbs_circle=undefined; //會觸發VBS對象的對象銷毀事件 //8.同一個域里面的Date類型的變量在JS代碼塊中也是可見的,其 // 類型也是date,但是它不是JS的date對象 alert("typeof vbs_date",typeof vbs_date); //date alert("vbs_date",vbs_date); //alert(vbs_date.getYear()); //報錯:為null或不是對象 var js_d=new Date(); alert("js_d.getYear()",js_d.getYear()); //9.同一個域里面的Err類型的變量在JS代碼塊中也是可見的,其 // 類型是object,成員不可遍歷 alert("typeof vbs_err",typeof vbs_err); //object alert(vbs_err+':'+vbs_err.Description+','+vbs_err.Source); for(i in vbs_err) //不可遍歷 alert(i); vbs_err.Clear(); alert(vbs_err+':'+vbs_err.Description+','+vbs_err.Source); })(); </script> <script id="vbs.main" language="VBScript"> WScript.Echo "==========================================================" Sub VBS_JS_TEST '1.同一個域里面的JS數組在VBS代碼塊中是可見的,其類型是JScriptTypeInfo, ' 但凡這種類型,其JS中原有定義的成員,都是可以原樣訪問的;數組通過索引 ' 取得元素,在這里會稍顯麻煩,需要依賴循環,沒有直接取得第N個元素的方法 ' 建議的方法是使用For Each循環將這個JScriptTypeInfo的數組轉換為VBS的數組 ' 再進行讀寫元素的操作 alert "typename(js_arr)",typename(js_arr) alert "js_arr",js_arr alert "js_arr.slice(1)",js_arr.slice(1) alert "js_arr.length",js_arr.length alert "For Each:" Dim i For Each i in js_arr alert i Next '2.同一個域里面的JS數字類型的變量在VBS代碼塊中也是可見的,其 ' 類型由原數字是否是整數決定,如果是小數,在VBS中表現為Double類型 ' 如果是一個整數,在VBS中會表現為Long類型 alert "typename(js_int)",typename(js_int) alert "js_int",js_int alert "typename(js_single)",typename(js_single) alert "js_single",js_single '3.同一個域里面的JS函數在VBS代碼塊中也是可見的,其類型一律是 ' JScriptTypeInfo alert "typename(js_func)",typename(js_func) alert "js_func(3,3.2)",js_func(3,3.2) alert "js_func(CByte(3),CCur(50))",js_func(CByte(3),CCur(50)) alert "js_func(Array(1,2,3),Nothing)", _ js_func(Array(1,2,3),Nothing) alert "js_func(Empty,Null)",js_func(Empty,Null) Dim vbs_arr1() alert "js_func(Now,vbs_arr1)",js_func(Now,vbs_arr1) alert "js_func('hello',true)",js_func("hello",true) alert "js_func(Err,New Circle)",js_func(Err,New Circle) alert "js_func(CreateObject('Scripting.FileSystemObject'))", _ js_func(CreateObject("Scripting.FileSystemObject")) '4.同一個域里面的JS字符串類型的變量在VBS代碼塊中也是可見的,其 ' 類型是String,與VBS字符串是互通的,VBS的字符串函數都可以直接用 alert "typename(js_str)",typename(js_str) alert "js_str",js_str alert "UCase(js_str)",UCase(js_str) '5.同一個域里面的JS布爾類型的變量在VBS代碼塊中也是可見的,其 ' 類型是Boolean,與VBS的布爾類型是互通的 alert "typename(js_bool)",typename(js_bool) alert "js_bool",js_bool '6.同一個域里面的Undefined類型的變量在VBS代碼塊中也是可見的,其 ' 類型是Empty,與VBS的Empty類型是互通的,在調用JS的函數/方法 ' 時在VBS中傳入Empty,在JS函數/方法中接受到的將是undefined alert "typename(js_undefined)",typename(js_undefined) WScript.Echo "js_undefined"+", "+js_undefined alert "js_undefined=Empty",js_undefined=Empty alert "js_func(3,Empty)",js_func(3,Empty) '7.同一個域里面的類類型的變量在VBS代碼塊中也是可見的,其類型是 ' JScriptTypeInfo,其原型定義的方法/屬性都可以正常訪問 js_square.Length=10 alert js_square.Length alert "typename(js_square)",typename(js_square) alert "js_square.GetArea()",js_square.GetArea() alert "js_square.GetArea.apply(js_square)",js_square.GetArea.apply(js_square) 'Set sq=New Square '報錯 '8.同一個域里面的Date類型的變量在VBS代碼塊中也是可見的,其 ' 類型也是JScriptTypeInfo,其原型定義的方法/屬性都可以正常訪問 alert "typename(js_date)",typename(js_date) alert "js_date",js_date alert "js_date.getYear()",js_date.getYear() 'alert Month(js_date) '因為它不是VBS的Date類型,所以VBS的日期時間函數無法處理它 '9.同一個域里面的Error類型的變量在VBS代碼塊中也是可見的,其 ' 類型是JScriptTypeInfo,其原型定義的方法/屬性都可以正常訪問 alert "typename(js_err)",typename(js_err) alert js_err.Number & ":" & js_err.Description End Sub Call VBS_JS_TEST </script> </job>

 這是一個wsf腳本,用記事本保存為wsf類型文本文件(比如wsf.wsf),即可運行,建議使用如下命令調用它(因為雙擊彈窗會很多,也不方便對比輸出):

CScript //nologo wsf.wsf

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM