<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