Hello…I am a bit confused about some results I am getting in debugger for the length of an array as returned by the length fx vs. the actual count of keys in the array.
In debug mode, when viewing the value of the varaible I see that the array has six keys (see pic 1) - this is correct
However when I use the length function on the array I am told the array has 10 keys (see pic 2) - this is incorrect
Huh? Any ideas…perhaps I am just missing something obvious.
Weird, I’m sure that array.length does work ok in Servoy 4.x (otherwise I would have an angry group of customers with torches and forks yelling at me… ), maybe the GUI shows only 6 because 4 of the slots are null?
Yeah it is pretty strange, but the “slots” are not null. You can set a key of an array to an any integer value you like (indexed) so long as that integer value is not a key already. The integer values of the keys do not need to be in order from 0-10… So yeah, I have no idea what is going on.
I do agree with you though that array.length does of course work generally, but have you ever tried to get the length of an array that has indexed keys that are not incremental integers? That may be the sticking point here.
How do you build the array? If you use var array = New Array(10) and then you only fill 6 values… maybe this is a test to perform to see how the GUI behaves.
That behavior is actually correct. I think the debugger should show you the undefined values, but Javascript arrays are allocated as positions are accessed, and you can’t have “missing” array indexes. If you set a higher array index, the intermediate values are allocated automatically, as ‘undefined’ values. So…
var a = new Array();
a.length; // 0
a[6] = 'value';
a.length; // 7
a[1] == undefined; // true!
This is not a Servoy thing. It’s standard JavaScript.
I can’t comment on the debugger. Frankly, I’ve been finding I don’t trust the variable display in the debugger much at the moment. Try adding a watch expression for your array.length and you’ll get the right value, I bet.
I just fired up the console in Firebug/Firefox and ran some tests against SeaMonkey for a reference implementation.
It’s a little complicated, in the sense that those values are considered allocated – but because of the way the iteration evaluator works, if you of a for(item in array), you will only pop of the values you’ve assigned, because it ignores undefined values. So…
var a = new Array();
a[5] = 'value';
a[3] = null;
var ct = 0;
for(item in a) ct++;
ct; // 2
a.length; // 6
So, the “length” of the array and the number of items in the array are really two different things.
Array.length
Every Array has a length property. This always contains the number of elements in the array. Since Arrays always start at zero, the length property is convenient for loops since it will always be one greater than the actual index. For instance if the Array has 10 elements then the indexes will be 0-9, so as long as our counter is less than the Array.length we’ll cover the entire Array…
for (var i=0; i<myArray.length; i++) {}
Going back to our undefined example above. Even though 3 of the Array items are undefined the length property will still count them because it’s always one higher than the highest accessable index value.
var myArray = [];
myArray[0] = ‘January’;
myArray[1] = ‘February’;
myArray[5] = ‘March’;
document.writeln(‘0>’+myArray[0]+’
‘); // Will output: 0>January
document.writeln(‘1>’+myArray[1]+’
‘); // Will output: 1>February
document.writeln(‘2>’+myArray[2]+’
‘); // Will output: 2>undefined
document.writeln(‘3>’+myArray[3]+’
‘); // Will output: 3>undefined
document.writeln(‘4>’+myArray[4]+’
‘); // Will output: 4>undefined
document.writeln(‘5>’+myArray[5]+’
'); // Will output: 5>March
document.writeln('Array Length: '+myArray.length); // Will output: Array Length: 6
Array.length is NOT a read-only value, you can set it as you wish. If you have 100 elements in an array and set the length to 50, Javascript will truncate the last 50 elements from the array (effectively deleting them). If you have 10 elements in an array and set Array.length to 100 then the length of the array will be expanded to 100, creating 90 undefined elements after the original 10 items.
Understanding all of this now basically as you say length is only really the length when it is really the length. The rest of the time it is not Makes sense to me.
Now regarding the debugger, I think it would make sense if the displayed length of the array in the debugger actually matched the value to be returned from the length fx itself. But maybe other’s have a reason why it should not?
Thinking though it would be easy enough to just extend the JS Array proto and add a “trueLength” fx which spits back a count from a for in loop. I think will do that.
You might want to play with mod_js_core if you’re working with Arrays. It implements all the Array extensions in the Prototype library – see: http://prototypejs.org/api/array