VBScript vs. JScript
Brian Lalonde
VBScript and JScript are extremely lightweight ActiveX Scripting languages. ActiveX Scripting Engines may be used in a variety of Microsoft environments: Windows Scripting Host, HyperText Applications, HyperText Components and scripting for Internet Explorer, and classic Active Server Pages. There are other ActiveX Scripting languages, such as ActivePerl and ActivePython, but these tend to be complete languages in contrast to the minimal logic layer that VBScript and JScript provide. In fact, VBS/JS must use ActiveX/COM components to accomplish anything other than trivial tasks. This optimization results in some noteworthy shortcomings in both languages.
VBScript Strengths
- The De Facto Standard
VBScript is typically the default scripting language for ActiveX Scripting environments, and so is used far more widely than any other scripting engine. The English-like syntax is arguably more approachable for less technical users. VBScript SafeArrays are typically the type of array expected by COM components (e.g. the ActiveDirectory Filter property).
- By Reference Parameters
Multiple, bidirectional, or large arguments may be passed ByRef
. This bypasses creating a local copy of the variable (increasing efficiency for large values), and allows the function or subroutine to make changes to a variable passed to it.
- Formatting Functions
FormatCurrency
, FormatDateTime
, FormatNumber
, and FormatPercent
not only make short work of tedious formatting tasks, but also use locale-specific formatting rules.
- Data Conversion
CBool
, CByte
, CCur
, CDate
, CDbl
, CInt
, CLng
, CSng
, and CStr
all tend to overreact to unconvertable data by throwing runtime errors, but are complemented by VarType
, IsDate
, IsEmpty
, IsNull
, IsNumeric
, and IsObject
. Hex
and Oct
allow converting numbers to non-decimal strings (though no functions are provided to do the inverse). DateValue
and TimeValue
allow returning just the parsed date or time values, respectively.
- Date/Time Support
Along with the usual functions for individual date fields, Day
, Hour
, Minute
, Month
, MonthName
, Second
, Timer
, Weekday
, WeekdayName
, Year
, and the more generic DatePart
, there are some more granular functions for current info: Now
, Date
, Time
. The DateSerial
and TimeSerial
functions allow for complex date arithmetic, as do DateAdd
, DateDiff
. Date literals are supported, using #
as the delimiter: #
datestring#
(using various formats). Durations can be stored as date/time values, except month durations.
- Built-In Iterator Support
Collections (objects containing multiple values that can only be accessed one after the other, starting at the first) can be iterated natively using For Each
.
- Constants
VBScript supports true constants, which are faster than alternatives (variables or functions), and enforce the read-only nature of constants.
With
Blocks
Using With
allows you to perform several operations on an object without using a temporary variable. It is particularly well-suited to DOM programming. The VBScript syntax for With
blocks is unambiguous, so there are no performance or readablity drawbacks.
With
xml.appendChild(xml.createElement("category"))
.setAttribute("id",id)
.setAttribute("keywords",keywords)
With
.appendChild(xml.createElement("item"))
.setAttribute("count",count)
.setAttribute("tip",tip)
.appendChild(xml.createTextNode(text))
End
With
End
With
VBScript Weaknesses
- Unforgivably Bad Array Support
While standard functions like Filter
, Join
, and Split
- Inefficient String Concatenation
Appending to strings in VBScript is shockingly slow. VBScript code should avoid repeated concatenation whenever possible.
- No UTC Support
Date/time values cannot be reliably converted between UTC and local timezones, since there is no way to determine either the local timezone or Daylight Saving Time (Summer Time in
- Clumsy Exception Handling
Automatic exception handling has two modes: on (all errors and warnings are fatal), and off. Modern, structured exception handling is not supported.
- Unreasonably Strong Typing
Objects are not first-class objects; assignment, for example, is handled completely differently from built-in datatypes. Passing functions as arguments requires using the GetRef
keyword. Adding to this difficulty, naught is expressed in many distinct (and confusing) terms: Nothing
is an invalid object variable, Null
adds the database-style complexity of three-valued logic (not true, but not false either), and Empty
is the value in an uninitialized variable. Numeric values can be interpreted as booleans, as can some string values (but only if they are numeric or boolean strings):
VBScript Boolean Conversion
Expression |
Value |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Error |
|
|
|
|
|
Error |
- No Short-Circuit Operators
The only way to avoid evaluating conditions in VBScript is to put them into separate If
statements. This means much more verbose code when the second condition relies on the success of the previous one:
' Wrong
If
Not
conn
Is
Nothing
And
conn.State
=
ADODB.adStateOpen
Then
' won't work
' continue
Else
' problem
End
If
' Redundant Workaround
If
Not
conn
Is
Nothing
Then
If
conn.State
=
ADODB.adStateOpen
Then
' continue
Else
' problem (first time)
End
If
Else
' problem (again)
End
If
' Manual Short-Circuit Workaround
Dim
ok
ok=
Not
conn
Is
Nothing
If
ok
Then
ok=
conn.State
=
ADODB.adStateOpen
' conditional second test
If
ok
Then
' continue
Else
' problem
End
If
JScript Strengths
- JavaScript/ECMAScript Overlap
Anyone familiar with client-side web scripting can start using JScript right away.
- Strong Array Support
A reasonable complement of expected array functions is supported: sort
, split
, join
, slice
, splice
, concat
, push
, pop
, shift
, unshift
, and reverse
. No grep/filter, search, or membership-test function are provided.
- Native Associative Arrays (hashes)
Actually, all JScript arrays are hashes: an array with numeric keys can have string keys added, and all keys can be iterated via the for
...in
loop. As Perl programmers already know, native hash support allows arbitrarily complex data structures to be built quite easily.
- Structured Exception Handling
Using try
...catch
, errors can be handled much more readably, maintainably, and conveniently.
- Conditional Compilation
Specially formatted comments can be used to hide code from the scripting engine based on platform or JScript version for last-minute optimization.
- UTC Support
Date/time values can be converted between UTC and local timezones, even handling Daylight Saving Time (Summer Time in
- Short-Circuit Boolean Operators
JScript stops evaluating a conditional expression as soon as it knows the outcome, skipping superfluous subexpressions. Not only is this more efficient, but it enables subexpressions to assume previous subexpressions have succeeded:
if(conn && conn.State == ADODB.adStateOpen)
conn.Execute(SQL);
JScript Weaknesses
- No Reference Argument Support
Any COM components that require reference parameters are completely useless to JScript.
- Unconventional
Tool support for JScript tends to be somewhat scarcer than VBScript. Productive familiarity with the language is also less common, particularly outside of web development groups.
- Stunningly Inadequate Formatting Facilities
All languages should have some kind of formatting ability: C's (and Perl's) printf
, C++'s iomanip.h
library, Python's %
operator, etc. JScript has only toFixed
and toExponential
for specifying the number of digits a number should include after the decimal. Doing something as simple as grouping digits in a number is incredibly tedious. Localized formatting is completely out of the question.
- Limited Data Conversion Support
Dates and non-decimal numbers (e.g. hexadecimal strings) are not converted natively.
- Limited Data Types
No native currency (fixed decimal) type is supported, so rounding errors may have a tendency to creep into many calculations. In fact, all numbers are treated as double floating point; no integer, long integer, or single float types are available.
- Lousy Date/Time Support
No functions exist specifically for date/time arithmetic, and there is an inadequate granularity for parsing control. No date literal is supported.
- No Constants
Special values must be stored in variables, or trivial functions, neither of which are optimal.
- Poor
with
Blocks
Since the syntax for with
blocks in JScript is ambiguous, members (indeed, all variables and functions within the block) must be searched for and bound at runtime. Without any distinguishing features, it is also impossible to see which items are members of the with
object when reading the code.
with(o)
{
a=x;
// o.a=x or a=o.x or o.a=o.x or just a=x ?
M(w);
// o.M(w) or M(o.w) or o.M(o.w) or just M(w) ?
}
The interpreter (and the reader) has no way to know which items within the with
block are members of o
, so it has to wait until runtime and painstakingly check each item.
- Clumsy Collection Iteration
Looping over items in a collection requires an Enumerator
object.
for(var e= new Enumerator(fso.Drives); !e.atEnd(); e.moveNext())
{
WScript.Echo(e.item().DriveLetter);
}