VB 程序
Sub 与 Function、参数传递、ByVal / ByRef、递归与可选参数。
Sub
Sub Greet(name)
WScript.Echo "Hello, " & name
End Sub
Call Greet("Ada")
Greet "Bob" ' 不用 Call 时不能加括号Hello, Ada
Hello, BobCall Greet("Ada") and Greet "Bob" both work, but Greet("Bob") does not: without Call, parentheses are parsed as passing a single expression and multi-argument calls fail.
Function
Function Add(a, b)
Add = a + b
End Function
Function IsEven(n)
If n Mod 2 = 0 Then
IsEven = True
Else
IsEven = False
End If
End Function
WScript.Echo Add(3, 4)
WScript.Echo IsEven(10)
WScript.Echo IsEven(7)7
True
FalseReturn by assigning to the function name; there is no return. A missing assignment yields Empty with no error, so assign on every branch, especially both paths of an If.
ByVal 与 ByRef
Sub ChangeRef(x)
x = x + 1
End Sub
Sub ChangeVal(ByVal x)
x = x + 1
End Sub
Dim a, b
a = 10 : b = 10
ChangeRef a
ChangeVal b
WScript.Echo a & " / " & b11 / 10Parameters are ByRef by default, so changes propagate to the caller — unlike Java, C# and Python. Write ByVal explicitly unless you intend to write back.
可选参数
Function Greeting(name, Optional title = "先生")
Greeting = "你好," & name & title
End Function
WScript.Echo Greeting("张伟")
WScript.Echo Greeting("李娜", "女士")你好,张伟先生
你好,李娜女士Optional parameters must come last and need a default. Skipping a middle one uses an empty slot: F(a, , c) — poor readability, so prefer a dictionary for many parameters.
递归
Function Fact(n)
If n <= 1 Then
Fact = 1
Else
Fact = n * Fact(n - 1)
End If
End Function
Function Fib(n)
If n < 2 Then
Fib = n
Else
Fib = Fib(n - 1) + Fib(n - 2)
End If
End Function
WScript.Echo Fact(5)
WScript.Echo Fib(10)120
55Naive Fib is exponential: Fib(35) takes seconds. VBScript has no tail-call optimisation and deep recursion overflows the stack — prefer loops in production scripts.
作用域与 Exit
Sub Demo()
Dim i
For i = 1 To 10
If i = 3 Then Exit Sub ' 提前退出过程
Next
End Sub
Function Find(arr, target)
Dim i
Find = -1
For i = LBound(arr) To UBound(arr)
If arr(i) = target Then
Find = i
Exit Function ' 提前返回
End If
Next
End FunctionExit Sub / Exit Function are the only early exits — there is no break or continue. To skip an iteration, wrap the body in an If.
Sub
Sub Greet(name)
WScript.Echo "Hello, " & name
End Sub
Call Greet("Ada")
Greet "Bob" ' 不用 Call 时不能加括号Hello, Ada
Hello, BobCall Greet("Ada") 和 Greet "Bob" 都对,但 Greet("Bob") 是错的——不带 Call 时加括号会被解析成「传一个表达式」,多参数时直接报错。
Function
Function Add(a, b)
Add = a + b
End Function
Function IsEven(n)
If n Mod 2 = 0 Then
IsEven = True
Else
IsEven = False
End If
End Function
WScript.Echo Add(3, 4)
WScript.Echo IsEven(10)
WScript.Echo IsEven(7)7
True
False返回值靠给函数名赋值,没有 return。漏赋值时返回 Empty,不报错——所以每个分支都要赋值,尤其是 If 的两条路径。
ByVal 与 ByRef
Sub ChangeRef(x)
x = x + 1
End Sub
Sub ChangeVal(ByVal x)
x = x + 1
End Sub
Dim a, b
a = 10 : b = 10
ChangeRef a
ChangeVal b
WScript.Echo a & " / " & b11 / 10默认 ByRef,函数内改动会影响调用方的变量。这与 Java、C#、Python 的默认行为都不同,从那些语言转过来最容易踩这个坑。不需要回写时一律显式写 ByVal。
可选参数
Function Greeting(name, Optional title = "先生")
Greeting = "你好," & name & title
End Function
WScript.Echo Greeting("张伟")
WScript.Echo Greeting("李娜", "女士")你好,张伟先生
你好,李娜女士Optional 必须放在参数列表末尾,且要给默认值。跳过中间的可选参数用逗号占位:F(a, , c)——这种写法可读性差,参数多时建议改用字典传参。
递归
Function Fact(n)
If n <= 1 Then
Fact = 1
Else
Fact = n * Fact(n - 1)
End If
End Function
Function Fib(n)
If n < 2 Then
Fib = n
Else
Fib = Fib(n - 1) + Fib(n - 2)
End If
End Function
WScript.Echo Fact(5)
WScript.Echo Fib(10)120
55Fib 的朴素递归是指数复杂度,Fib(35) 就要跑好几秒。VBScript 没有尾调用优化,递归深度大时还会栈溢出——生产脚本里能改成循环就改成循环。
作用域与 Exit
Sub Demo()
Dim i
For i = 1 To 10
If i = 3 Then Exit Sub ' 提前退出过程
Next
End Sub
Function Find(arr, target)
Dim i
Find = -1
For i = LBound(arr) To UBound(arr)
If arr(i) = target Then
Find = i
Exit Function ' 提前返回
End If
Next
End FunctionExit Sub / Exit Function 是 VBScript 里唯一的提前退出方式,没有 break 和 continue。想「跳过本次循环」,只能把条件写进 If 块里。