The JScript Type System Part Seven: Yeah, you’ve probably guessed that I wrote the array stuff

reader asked me to clarify a point made in an earlier entry:


that JScript .NET arrays do not have any of the methods or properties of a CLR array.
(Strings, by contract, can be used implicitly as either JScript .NET strings or as
System.String values,
which I’ll talk more about later.) But JScript .NET arrays do not have CLR array fields
Rank, SetValue,
and so on.


actually pretty straightforward.  When
you have a string in a JScript .NET program, we allow you to treat it as both a System.String
and as a JScript object with the String prototype.  For


var s
= “   hello   “;

// calls JScript string prototype’s toUpperCase

// calls System.String.Trim


is it?  From a theoretical standpoint,
it doesn’t really matter — you can use it as either.  From
an implementation standpoint, of course we use System.String internally and magic
up the prototype instance when we need one — just as in JScript classic all strings
are VT_BSTR variants internally and we magic up a wrapper when we need one.  So
JScript strings and CLR strings really are totally interoperable.


aren’t quite so seamless.  As I mentioned
earlier, when you try to use a JScript .NET array when a CLR array is expected, we
create a copy.  But when you go the other
way, things are a little different. Rather than producing a copy, using a CLR array
as a JScript .NET array “wraps it up”. No copy is made. The operation is therefore
efficient and preserves identity. Changes
made to a wrapped array are preserved:


ChangeArray(arr : Array) : void


// 10

+= 100;

JScript .NET methods work just fine

// 10:20:30


var arr
: int[] = [10, 20, 30];


// 110


principle rule for treating a hard-typed array as a JScript .NET array is that it
must be single-dimensional
. Since all JScript .NET arrays are single-dimensional
it makes no sense to wrap up a high-rank CLR array.


the array is wrapped up it still has all the restrictions that a normal hard-typed
array has. It may not change size, for instance. This means that an attempt to call
certain members of the JScript .NET Array prototype on a wrapped array will fail.
All calls to
push, pop, shift, unshift and concat as
well as some calls to
splice will
change the length of the array and are therefore illegal on wrapped CLR arrays.


that you may use the other JScript .NET array prototype methods on any hard-typed
array (but not vice versa). You can think of this as implicitly creating a wrapper
around the CLR array, much as a wrapper is implicitly created when calling methods
on numbers, Booleans or strings:


var arr
: int[] = [10, 20, 30];

arr.reverse();    //
You may call JScript .NET methods on hard-typed arrays

print(arr.join(“:”));   //


may be a situation where you do want to
make a copy of a CLR array rather than wrapping it. JScript .NET has syntax for this,


var sysarr
: int[] = [10, 20, 30];

var jsarr1
: Array = sysarr; // create wrapper without copy

var jsarr2
: Array = Array(sysarr); // create wrapper without copy

var jsarr3
: Array = new Array(sysarr); // not a wrapper; copies contents


the last case
jsarr3 is
not a wrapper. It is a real JScript .NET array and may be resized.

Comments (3)

  1. Dan Shappir says:

    I think some of that reader’s misunderstanding is a result of the use of the word "contract" where the word "contrast" was intended.

    In any event, thanks for the info.
    A question though: suppose I had changed the ChangeArray implementation to:

    function ChangeArray(arr) : void
    print(arr[0]); // 10
    arr[0] += 100;

    Would it still convert the CLR array to a JScript.NET array? Or have I created a generic function that works for both types with no conversions?

  2. Peter Torr says:

    Dan, your changed function does not specify a type for the ‘arr’ parameter, so it will be compiled as "Object" and all operations on ‘arr’ will be late-bound. Thus it will work with JScript arrays, CLR arrays, and indeed anything that has an overloaded indexing operator.

  3. Eric Lippert says:

    Yeah, I guess the spell checker didn’t catch that one, did it? 🙂