Reputation: 11499
I pass in an array of error messages to parse. An example input would be:
"An item with this x Id already exists.
An item with this y id already exists.
An item with this barcode already exists.
"
That is, the string is literally each line above separated by a \n, with a final \n at the end.
function( msg )
{
alert( "\"" + msg + "\"" );
var aLines = msg.split( /\r?\n+/ );
for ( var i in aLines )
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
}
I split it into lines, and iterate over the lines. At index 3 there is no line and the first conditional triggers. Should that not be an empty line? e.g. ""
Then the loop actually goes one more element to 4, and shows a the contents of a function.
That is I get - five alerts:
0: "An item with this x Id already exists."
1: "An item with this y id already exists."
2: "An item with this barcode already exists."
Error!
The last one is most bizarre:
hasObject: "function(o) {
var l = this.length + 1;
... more lines ...
}
I don't understand what is happening here. Why is it iterating over one more element? And why is the last element a function? And shouldn't offset 3 be an empty string? That is I should not be alerting "Error!" here.
Upvotes: 0
Views: 201
Reputation: 40507
You are getting Error!
in end because the splitting is giving you empty line ""
and when you check for it with if(!aLines[i])
it returns true
because it is empty/null/nothing. You can check it here in a fiddle, you remove the empty line from end and it does not go over array 4 times.
I have also put in following code which shows alert:
var a="";
if(!a){
alert("!a");
}
Upvotes: 0
Reputation: 1293
As jbabey said, using for .. in
loops in Javascript is risky and undeterministic (random order--sometimes). You would most commonly use that for parsing through objects in associative arrays.
But, if you insist on keeping the for .. in
, wrap the inside of the for
with an if
block like such:
for (var i in aLines)
{
if(aLines.hasOwnProperty(i))
{
// ... Do stuff here
}
}
Otherwise, just change it to a classic incremental for
loop to get rid of that error:
for (var i = 0; i < aLines.length; i++)
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
Upvotes: 1
Reputation: 5254
You should use a regular for loop for arrays, because for-in will also return all the other property keys in the Array object. This is why you are seeing "hasObject" (and in my browser, I see a lot more after that): because your array has the function "hasObject", so when you enumerate all of Array's properties this comes up.
The correct for-loop:
for ( var i = 0, ii = aLines.length; i<ii; i++ )
{
if ( !aLines[i] ) { alert( "Error!" ); continue; }
alert( i + ": \"" + aLines[i] + "\"" );
}
Here is your code with the for-in loop replaced with a for loop, and it works as expected:
http://jsfiddle.net/SamFent/4rzTh/
Upvotes: 1
Reputation: 46647
Never loop over an array with for...in.
Iterates over the enumerable properties of an object, in arbitrary order.
Why is using "for...in" with array iteration a bad idea?
Upvotes: 5