VBS过程和函数参数传递的方式默认是ByVal还是ByRef?

标签: , , , , , , ,

我一直以为 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 以外,该脚本还说明了当用括号把表达式括起来的时候,内部会创建一个临时变量来保存括号中表达式的值。

赞赏

微信赞赏支付宝赞赏

随机文章:

  1. PT作弊工具之uSerenity
  2. 在WSH中使用jQuery
  3. 在Raspberry Pi树莓派上编译Node.js
  4. PHP函数源码中的return_value变量
  5. 跨编译器的 C 语言 NaN 支持

4 条评论 发表在“VBS过程和函数参数传递的方式默认是ByVal还是ByRef?”上

  1. Mark Andersen说道:

    虽然今天才看到您的这篇文章,顺手也回复一下。关于传址和传值的错误确实很误导,完全相反。另外,对于将对象作为过程参数的话,无论指定ByVal与否,都是传址。VBS对于对象变量相当于只保留一个别名。等同于在参数中使用了SET关键词。以前编程需要做了一个由VBS生成对象传递到Excel VBA的过程中的软件,发现这个问题。不知道这个认识是否正确?

  2. […] 今天有网友在《VBS过程和函数参数传递的方式默认是ByVal还是ByRef?》中回复: […]

  3. PY-DNG说道:

    原来括号还有这个作用,学到了

    其实我今天测试的时候还发现一点,就是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)
    无论定义是什么都会只传值,不传址

    个人见解,测试结果如有错误,请好心人指正,谢谢

留下回复