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.
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.
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++;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With