Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Select2 each2 method - how does it work?

I was looking through Select2 (source code) and found each2 method prototype:

$.extend($.fn, {
  each2 : function (c) {
    var j = $([0]), i = -1, l = this.length;
    while (
      ++i < l
       && (j.context = j[0] = this[i])
       && c.call(j[0], i, j) !== false //"this"=DOM, i=index, j=jQuery object
     );
     return this;
   }
});

My question is - how this method works? I mean - why there is while loop only with condition, without statement part? I'd really love to understand this method's flow.

like image 799
nd_macias Avatar asked Oct 22 '14 17:10

nd_macias


1 Answers

When you put an expression inside a condition (for instance: if (i), if (i == null), if (++i), if (i < 2))) the expression get evaluated before its 'checked' is it true or false.

Live example:

we have var i = 0; now you call if (++i) console.log(i). The expression ++i return 1 (it is understood as truth in javascript [0 is not]) so console.log(i) logs 1.

Now let's say we have var i = 0 and if (++i && ++i) console.log(i). The first expressions returns 1 so the second is also called which returns 2. Both 1 and 2 are treated as truth so console.log(i) logs 2

Awesome. Let's have a look on the same example as above but before if we initialise var i = -1 . Now we call if (++i && ++i) console.log(i). The first ++i returns 0 which is falsity.

To continue you have to get how && works. Let me explain quickly: If you stack exp1 && exp2 && exp3 ... && expX then exp2 will be only executed(evaluated) when exp1 returns truth (for instance: true, 1, "some string"). exp3 will be executed only if exp2 is truthy, exp4 when exp3 is truth and so on...(until we hit expN)

Let's go back to f (++i && ++i) console.log(i) now. So the first ++i returns 0 which is falsity so second ++i isn't executed and whole condition is false so console.log(i) won't be executed (How ever incrementation was completed so i equals to 0 now).

Now when you get it I can tell you that while loop works the same in condition checking way. For instance var = -2 and while (++i) will be executed until ++i returns falsity (that is 0). while (++1) will be executed exactly 2 times.

TL;DR BELOW!!!

So how this works?

   while (
      ++i < l
       && (j.context = j[0] = this[i])
       && c.call(j[0], i, j) !== false
     );

I think the best way to explain is to rewrite it (:

   while ( ++i < l ) {
       if (!(j.context = j[0] = this[i])) break;
       if (!(c.call(j[0], i, j) !== false)) break;
   }

or ever less magical:

   var i = 0;
   while ( i < l ) {
       if (!(j.context = j[0] = this[i])) break;
       if (!(c.call(j[0], i, j) !== false)) break;
       i++;
   }
like image 121
Filip Bartuzi Avatar answered Sep 21 '22 18:09

Filip Bartuzi