If there’s anyone who can help me understand this one, I will be impressed. It’s #28 from John Resig’s advanced JavaScript.
Here’s a function for looping, and, if you look at the tutorial, it seems to run 3 times producing the 6 Pass below.
Can you please explain in plain language in as much detail as possible what is happening in this program, explaining along the way:
-
fn.call(array, array[i], i)Why are there these 3 parameters to the function and how do they all work. Does the function first deal with array, then array[i], and then i? What’s happening when all that is going on? -
Also, in the function, I understand that
i++goes up every time that it goes through the array.length, but what triggersnum++to increase it’s value, and in what way isvalue == num++ -
In
function(value, i), what isvalue? Is value alternately 0,1,2 of the loop array? If so, how do those loop array numbers get passed as a parameter infunction(value, i) -
this instanceof Arraywhat is this trying to show? How?.
Code:
function loop(array, fn){
for ( var i = 0; i < array.length; i++ )
fn.call( array, array[i], i );
}
var num = 0;
loop([0, 1, 2], function(value, i){
assert(value == num++, "Make sure the contents are as we expect it.");
assert(this instanceof Array, "The context should be the full array.");
});
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
PASS Make sure the contents are as we expect it.
PASS The context should be the full array.
The
functionis an anonymous function, that is, a function without a name. The full second argument toloopiswhich is a complete anonymous function which takes three arguments:
this(the object for which it is a method), the current value, and the loop counter.loopiterates over the array, and usesfn.callto invoke the anonymous function, passing it three arguments; here, the array object must be explicit, becausecallcan’t know what context the function reference it’s being invoked on should be invoked in (that is, what to makethisin the call).The anonymous function, as invoked by
loop, receives the array asthis. The secondASSERTverifies this. It also expects that the array’s value is[0, 1, 2]and verifies this by incrementingnumon each call and comparing that to the passed array element.So, following the execution chain:
numis declared and initialized to 0.loop([0, 1, 2], function ...)is invoked.loopinvokesfn, the anonymous function, with the array (asthis), its first element, andiwhich indicates the element offset. (iis never actually used.)ASSERTs that it was passed the expected first element, 0, by comparing againstnumand incrementingnumafterward.ASSERTs that itsthisis anArray.loopinvokesfnas in #3, but with the second array element.ASSERTs, this time comparing the passed second array element, which is expected to be 1, againstnum(which, because of the post-increment in step 4, is 1).loopinvokesfnas before with the third array element.ASSERTs again, this time comparing the expected array element 2 againstnumwhose value is now 2.