标题: VBS过程和函数参数传递的方式默认是ByVal还是ByRef?
作者: Demon
链接: https://demon.tw/programming/vbs-byval-byref.html
版权: 本博客的所有文章,都遵守“署名-非商业性使用-相同方式共享 2.5 中国大陆”协议条款。
我一直以为 VBS 过程和函数参数传递的方式默认是 ByVal,直到我膝盖中了一箭。
在《VBScript Programmers Reference》一书的101页和102页有这样一段文字:
There is one concept that was skipped during the introduction to procedure and function arguments: passing arguments by reference versus passing arguments by value . An argument is defined either by reference or by value depending on how it is declared in the procedure or function definition. A by-reference argument is indicated with the ByRef keyword, whereas a by-value argument can either be indicated with the ByVal keyword or by not specifying either ByRef or ByVal — that is, if you do not specify one or the other explicitly; ByVal is the default.
在介绍过程和函数的参数时跳过了一个概念:传址和传值。一个参数是传址还是传值取决于过程或函数定义中的声明。传址的参数用 ByRef 关键字说明,而传值的参数既可以用 ByVal 关键字说明也可以不加任何说明——也就是说,没有明确地指定是哪一种的话,ByVal 就是默认值。
只可惜这段文字是错误的,VBS 过程和函数参数传递的方式默认是 ByRef,测试如下:
Function f(x, y) t = x x = y y = t End Function 'Author: Demon 'Website: https://demon.tw 'Date: 2012/2/5 x = 123 : y = 456 f x, y WScript.Echo x, y '输出456 123 x = 123 : y = 456 f (x), (y) WScript.Echo x, y '输出123 456 x = 123 : y = 456 Call f(x, y) WScript.Echo x, y '输出456 123 x = 123 : y = 456 Call f((x), (y)) WScript.Echo x, y '输出123 456 x = 123 : y = 456 z = f(x, y) WScript.Echo x, y '输出456 123 x = 123 : y = 456 z = f((x), (y)) WScript.Echo x, y '输出123 456
除了证明 VBS 过程和函数参数传递的方式默认是 ByRef 以外,该脚本还说明了当用括号把表达式括起来的时候,内部会创建一个临时变量来保存括号中表达式的值。
赞赏微信赞赏支付宝赞赏
随机文章:
虽然今天才看到您的这篇文章,顺手也回复一下。关于传址和传值的错误确实很误导,完全相反。另外,对于将对象作为过程参数的话,无论指定ByVal与否,都是传址。VBS对于对象变量相当于只保留一个别名。等同于在参数中使用了SET关键词。以前编程需要做了一个由VBS生成对象传递到Excel VBA的过程中的软件,发现这个问题。不知道这个认识是否正确?
很遗憾,并不正确,详见http://demon.tw/programming/vbs-object-byval-byref.html
[…] 今天有网友在《VBS过程和函数参数传递的方式默认是ByVal还是ByRef?》中回复: […]
原来括号还有这个作用,学到了
其实我今天测试的时候还发现一点,就是func arg1, arg2、Call func(arg1, arg2)和Var = func(arg1, arg2)在arg1, arg2没有单独加括号时都会遵循定义时的ByVal以及ByRef关键字进行传值或者传址,但是直接使用func(arg1, arg2)则只会传值不会传址(哪怕定义里面写明了ByRef也是这样,不知道和您所说的括号规则是不是一个原理),也就是说:
这三种写法:
func arg1, arg2
Call func(arg1, arg2)
Var = func(arg1, arg2)
该传值传值,该传址传址:
但是这两种写法:
func(arg1, arg2)
func (arg1), (arg2)
无论定义是什么都会只传值,不传址
个人见解,测试结果如有错误,请好心人指正,谢谢