I'd like to add: Don't define your array as nothing but a hashmap with
strings as array indexes, with two assignment hooks: One that on assignment updates that sets length = max(length, ToUint32(assigned key)), and one on "length" assignment that iterates over all keys in the hashmap, and for those that can be parsed as uint32's, delete those that have a numerical value larger than the value assigned to length.
That is how JavaScript "Array" objects work. Array indexes are coerced to a strings, as they are for all objects.
For the curious, here is full definition from ECMA-262 1st edition, which describe what browsers currently implement (https://www.ecma-international.org/publications/files/ECMA-S..., page 65):
Array objects give special treatment to a certain class of property names. A property name P (in the form of a string
value) is an array index if and only if ToString(ToUint32(P)) is equal to P and ToUint32(P) is not equal to 232−1.
Every Array object has a length property whose value is always an integer with positive sign and less than 232. It
is always the case that the length property is numerically greater than the name of every property whose name is
an array index; whenever a property of an Array object is created or changed, other properties are adjusted as
necessary to maintain this invariant. Specifically, whenever a property is added whose name is an array index, the
length property is changed, if necessary, to be one more than the numeric value of that array index; and whenever
the length property is changed, every property whose name is an array index whose value is not smaller than the
new length is automatically deleted. This constraint applies only to properties of the Array object itself and is
unaffected by length or array index properties that may be inherited from its prototype.