More On ByRef vs ByVal

In my previous entry I discussed VBScript’s various syntaxes for passing values by reference.  However it occurs to me that there may be some confusion about what exactly “byref” and “byval” mean in JScript and VBScript.  This is frequently a source of confusion, as VBScript has byref behaviour not supported by JScript.

The confusion arises because VBScript uses “by reference” to mean two similar, but different things.  VBScript supports reference types and variable references.  JScript supports the former but not the latter.

The best way to illustrate the difference is with an example.  Consider this class:

Class Foo 
      Public Bar
End Class

Now we can create an instance of this class:

Dim Blah, Baz
Set Blah = New Foo
Set Baz = Blah
Blah.Bar = 123

Both Blah and Baz are references to the same object.  The fourth line changes both Blah.Bar and Baz.Bar because these are different names for the same thing.

That’s the “reference type” feature.  We say that VBScript treats objects as reference types.

Now consider this little program:

Sub Change(ByRef XYZ) 
    XYZ = 5
End Sub
ABC = 123
Change ABC

This passes a reference to variable ABC.  The local variable XYZ becomes an alias for ABC, so the assignment XYZ = 5 changes ABC as well.

JScript has reference types — all object types are reference types.  But JScript does not support variable references.  There is no way for one scope to change the value of a variable in another scope.

UPDATE: articles on related topics can be found here:

Comments (7)

  1. I was talking about reference types vs. by-reference variables a while back. Recall that both JScript and VBScript have reference types (ie, objects) but JScript does not have by-reference variables. COM supports passing variable references around, but unfortunately the intersection of early-bound COM and late-bound IDispatch is a little bit goofy.

  2. David Reed says:

    Just thought I’d say for anyone else googling to this that in VBScript "By Reference" does not mean two different things. It _always_ means a pointer to the data rather than the data itself. I think what FAIC was getting at is that for intrinsic types (integer, float, string, etc) the variable contains the actual value (e.g. variable intX actually contains the number 3) whereas for object types the variable contains a pointer to the actual object (e.g. variable objX contains a memory location value a.k.a. a pointer to the object). Thus when dealing with objects, everything you do is implicilty "By Reference", wherea when dealing with intrinsic types, everything you do is implicitly by "By Value". Incidentally this does not affect the rules behind passing variables ByRef and ByVal i.e. passing an object variable ByRef allows you to change the variable value, in this case a the pointer to the object data, which means you can reassign it to another object whereas passing ByVal does not (however, and this is where people get confused, irrespective of passing an object variable ByRef or ByVal you can always change the underlying object data), and passing an intrinsic variable ByRef allows you to change the variable value, in this case the actual data, whereas passing ByVal does not. C programmers tend to understand all this implicilty because of their knowledge of pointers and how languages work under the hood, but VB programmers tend to have difficuly grasping what is going on because of thier lack of exposure to pointers.