5

I am trying to create an array for listing purposes in Ionic Framework and check all the callcenter name's first char to add them in an alphabet array.

  for (var i = 0; i < callcenterList.length; i++) {
    var value = callcenterList[i]._owner && callcenterList[i]._owner.company.name[0];

    if ((alphabet.indexOf(value) == -1 && isNaN(parseInt(value))) ||
      (isNaN(alphabet[0]) && !isNaN(value))) {
      if(!isNaN(value))
        value = 123;

      alphabet.push(value);

      callcenterList.splice(i, 0, {
        divider: {
          alphabet: value
        }
      });
    }
  };

Replacing value = 123 with value = '#' causes Google Chrome and Google Chrome Canary to malfunction and immediately use up to 100% of RAM in Mac.

Is this a Javascript bug or is it related to Google Chrome itself?

Icepickle
  • 12,689
  • 3
  • 34
  • 48
Yagiz
  • 1,033
  • 2
  • 21
  • 47
  • Never heard of that one before... – durbnpoisn Feb 18 '16 at 21:33
  • Does it make any difference if you use double quotes rather than single? – Mark Eriksson Feb 18 '16 at 21:38
  • 1
    Well, if it's #, then it's not part of the alphabet, and it's not a number, and since you limit your loop based on callcenterList.length (and push inside the loop) I don't think it has to do either with the # and neither with chrome? :) – Icepickle Feb 18 '16 at 21:38
  • @Icepickle isNaN('#') returns true. The problem is not related to changing value to 123 or # and whether it is a number or not. If I change value to ='AA', the problem doesnt appear. – Yagiz Feb 18 '16 at 21:42
  • @Yagiz, it's simply your fancy way of pushing an element into a list you are iterating that could cause serious problems, like the one you see here – Icepickle Feb 18 '16 at 21:45
  • @skobaljic Using array.length in for loop condition doesn't cause the browser to recalculate the array size again and again in each iteration. – Yagiz Feb 18 '16 at 21:46
  • @skobaljic since he is pushing at special indexes, he won't reach all indexes by taking the length before the loop starts. I would say, a copy of the list might be the simplest, safest solution to manipulate the data – Icepickle Feb 18 '16 at 21:47
  • @Yagiz Using array.length in for loop condition does cause the browser to recalculate/retrieve the array length on each iteration. – traktor Feb 18 '16 at 22:04
  • @Yagiz I changed the topic title and tags per this post http://meta.stackoverflow.com/questions/254216/should-i-edit-titles-which-have-nothing-to-do-with-the-actual-problem – Icepickle Feb 18 '16 at 22:05

2 Answers2

6

This isn't a bug in your browser or anything: you're just creating a condition where your code goes into an infinite loop, which always tends to make the browser seize up. You can do the same thing with a simple while (true) {} loop.

Specifically, you are iterating over the callcenterList, and any time isNaN(alphabet[0]), you are splicing a new element into callcenterList. alphabet[0] is going to have the first value that you push there which, in the conditional you're looking at, you're going to set to '#'.

Therefore, isNaN(alphabet[0]) will always be true.

Therefore, you'll continue to add values into callcenterList.

Therefore i < callcenterList.length will always be true.

StriplingWarrior
  • 151,543
  • 27
  • 246
  • 315
  • This is a simple for loop. And there isn't any condition that can create an infinite loop. Even if the "if" condition appears to be wrong, the for loop should continue to iterate. What am I doing wrong in this situation? – Yagiz Feb 18 '16 at 21:45
  • 1
    @Yagiz You are adding an element to the iterating array inside the loop with `splice`. Since this is done every time, `i` will never reach the length of the array. – E_net4 Feb 18 '16 at 21:48
  • @Yagiz: I added a more detailed explanation to my answer. Basically, what E_net4 said: you're increasing the length of your array with each iteration, so you'll never reach the end of it. – StriplingWarrior Feb 18 '16 at 21:51
  • It seems reasonable. Thank you. – Yagiz Feb 18 '16 at 21:51
1

Since it is hard to believe that length is being re-evaluated, here is a simple example of what problems you might get

Without the break statement, the code will run in an endless loop. (Check the console log for how long the list might be)

var list = [0,1,2,3];

for (var i = 0; i < list.length; i++) {
  list.push(i);
  if (i > 1000) {
    break;
  }
}

console.log( list.length );

Your code does exactly the same, except that your splice function will add the new element at the specific position of your list (nl, your index). In the end, it will still increase the length, and your list will be one longer

Icepickle
  • 12,689
  • 3
  • 34
  • 48