UIZE JavaScript Framework

2011 NEWS 2011-08-30 - Workaround for JScript For In Issue

An issue was discovered with the way that Microsoft's JScript interpreter, which is used in Internet Explorer and Windows Script Host, iterates through arrays in for...in loops.

Essentially, when an array is populated using literal syntax (e.g. [0,1,2,3]), and the value undefined is explicitly specified for some of the elements, then the elements whose values are set to undefined will not be encountered in a for...in loop.

EXAMPLE

var
  keysHash = {},
  myArray = ['foo',undefined,'bar'] // element 1 is explicitly initialized to undefined
;
for (key in myArray) {
  keysHash [key] = true;
}
alert (keysHash [1]);

In the above example, the alert statement would alert the value undefined in interpreters that exhibit the problematic behavior. This is because element one is not treated as enumerable by JScript in this case. Curiously, however, if the value undefined is explicitly assigned to the element, then JScript will treat the element as enumerable and it will be encountered in a for...in loop.

EXAMPLE

var
  keysHash = {},
  myArray = ['foo',undefined,'bar']
;

myArray [1] = undefined; // explicitly assigning the value undefined

for (key in myArray) {
  keysHash [key] = true;
}
alert (keysHash [1]);

In the above example, the alert statement alerts the value true - even in interpreters that exhibit the problematic behavior.

It's not clear why the literal syntax initialization produces a sparsely populated array in JScript when some elements are initialized to undefined. Regardless of the rationale, this inconsistent behavior causes a problem when using a for...in loop to compare arrays for identical elements and custom properties, as was the case with the previous implementation of the Uize.Data.identical method defined in the Uize.Data module.

Consider the following example...

EXAMPLE

var
  array1 = ['foo',undefined,'bar'],
  array2 = []
;
array2 [0] = 'foo';
array2 [1] = undefined;
array2 [2] = 'bar';

alert (Uize.Data.identical (array1,array2));  // alerted the value false before the workaround

A workaround was put in place to instead compare elements and custom properties in separate passes. With this workaround, the two arrays in the above example would be considered identical when running in JScript.