2

This is something that has been killing me for an hour. I'm trying to do a simple for loop over a string, and return the current character and the next character.

var mystring = "abcdef";

for (x in mystring) {
   if (mystring[x + 1]) {
      console.log(x + ": " + mystring[x] + mystring[x + 1]);
   }
   else {
      console.log("You've reached the end of the string");
   }
}

In every iteration of the loop, "mystring[x + 1]" is false. Though I would expect it to be true for the first five characters of the string. What is going on here? Is there something about JavaScript that I do not understand?

1 Answers1

8

for-in is for looping over the names of enumerable properties of an object. The property names are always strings*. string + number results in a string, using concatenation (e.g., "1" + 1 is "11", not 2).

So if you converted the property name to a number first, it might mostly work:

x = +x; // Convert to number
if (mystring[x + 1]) {

...but I would use

for (x = 0; x < mystring.length; ++x) {

...instead. If I needed to support old browsers, I'd also use .charAt(...) rather than [...] to get the character (but I think the browsers that didn't support indexing into strings are pretty dead these days).

Live example with just the x = +x:

var mystring = "abcdef";

for (x in mystring) {
   x = +x;
   if (mystring[x + 1]) {
      snippet.log(x + ": " + mystring[x] + mystring[x + 1]);
   }
   else {
      snippet.log("You've reached the end of the string");
   }
}
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

* "property names are always strings" That's true in ES5. In ES6+, they might also be Symbol instances, but for-in doesn't visit the ones that aren't strings. That's not relevant here, but I hate to leave a statement like that out there... :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875