<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
