ByRef vs. ByVal

 

VBS 中函数参数支持 ByVal ByRef 两种传递方式,它们的区别是什么呢?

 

ByRef 表示传递的是指向对象的指针,函数体内修改变量值时将直接修改指针所指向的对象值,参数定义时如果没有声明为 ByVal ByRef ,则默认为 ByRef ,例如:

msg = "DB MSG - Some junk from error message:SQL Err001"

Msgbox IsDBError(msg)

Msgbox msg

 

Function IsDBError(ByRef sMessage)   

       If inStr(sMessage, "DB") <= 0 Then       

              IsDBError = False       

              Exit Function   

       End If   

       sMessage = Replace(sMessage, "Some junk from error message:", "")   

       IsDBError = True

End Function

 

在这里调用 IsDBError 不仅返回布尔值,而且返回 ByRef 传递的修改后的变量值。

 

 

ByVal 表示传递的是对象的拷贝,函数体内修改的是局部变量的值。例如:

msg = "The field Value: abc"

Report msg

Msgbox msg

 

Function Report(ByVal Message)   

       Message = Replace(Message, "The field Value: ", "")   

       Msgbox (Message)

End Function

 

但是有个看起来像是例外的是 Dictionary ,例如下面的代码:

Sub AddValue(ByVal oDicationay)  

       oDicationay.Add "Some", "Thing"

End Sub

 

Set oDic = CreateObject("Scripting.Dictionary")

Call AddValue(oDic)

Msgbox oDic.Containes("Some") 'What will this print ,True or False?

按理, ByVal 是传递变量的拷贝,因此跳出 AddValue 函数体外之后应该取原来的变量值,但是这里脚本执行的结果是 True ,表明 AddValue 函数体内对变量值进行了直接的修改,其行为相当于 ByRef

 

原因是 oDic 对象并不是真正的 Dictionary 对象,而是指向 Dictionary 对象的指针,因此传递给 AddValue 的也不过是指针而已,最终修改的还是所指向的同一个 Dictionary 对象!

 


再来看下面的例子:

Sub DoIt(ByVal oDictionary)   

       oDictionary.Add "1", "1"   

       Set oDictionary = Nothing

End Sub

 

Sub DoIt2(ByRef oDictionary)   

       oDictionary.Add "2", "2"

       Set oDictionary = Nothing

End Sub

 

Set oDic = CreateObject("Scripting.Dictionary")

Call DoIt(oDic)

MsgBox oDic.Count 'What will this print?

Call DoIt2(oDic)

MsgBox oDic.Count 'What will this print?

 

两个 Sub 中都用了 Set oDictionary = Nothing ,但是由于 ByVal ByRef 的不同而产生不一样的结果:

第一个 Sub 中, ByVal 传递的是指向 oDic 对象的指针拷贝,因此设置为 Nothing 释放的是 oDictionary ,而不是 oDic ,因此 MsgBox 能显示 oDic Count 属性值。

而第二个 Sub 中, ByRef 传递的是指向 oDic 对象的指针,因此设置为 Nothing 释放的就是 oDic 本身,因此后面的 MsgBox 尝试显示已被销毁的 oDic 对象的属性值时发生错误:缺少对象‘ oDic !

 

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值