Sunday, 15 May 2016

javascript callback functions, variable mapping



I've always used callback functions in javascript, but I've never understood how the callback knows what variables it can take in.




Let's take the following example code;



var friends = ["Mike", "Stacy", "Andy", "Rick"];

friends.forEach(function (name, index){
console.log(index + 1 + ". " + name);
});



This logically outputs;



1. Mike 
2. Stacy
3. Andy
4. Rick


In fact, all of the following will output the same;




friends.forEach(function (index, name){
console.log(name + 1 + ". " + index);
});

friends.forEach(function (foo, bar){
console.log(bar + 1 + ". " + foo);
});

friends.forEach(function (x, y){
console.log(y + 1 + ". " + x);

});


How does the callback function within forEach know how to interpret name and index? In other words; how does the callback know that the array has values and indexes? It is clear that the name you give to the input variables of the callback function aren't important but the order is, so how are things mapped?



From here I would also like to apply this knowledge to other objects in general, not just lists. So how are variables mapped from the object into the callback functions? Is this something that is defined beforehand in the object?


Answer



In browsers that support Array.prototype.forEach natively it may be implemented differently, but in general you'd use Function.prototype.call to execute the callback function provided with arguments in the correct order (whatever that may be) whilst iterating through your collection.



The MDN entry for forEach has the following code for implementing it for arrays in browsers that don't support it:




if (!Array.prototype.forEach) {
Array.prototype.forEach = function (fn, scope) {
'use strict';
var i, len;
for (i = 0, len = this.length; i < len; ++i) {
if (i in this) {
fn.call(scope, this[i], i, this);
}
}

};
}



In other words; how does the callback know that the array has values and indexes? It is clear that the name you give to the input variables of the callback function aren't important but the order is, so how are things mapped?




To elaborate, the callback function is just a function like any other, with parameters that can be arbitrarily named (a and b works just as well as index and value); before it's executed it doesn't know anything about the array. The array that you're calling forEach on knows that it has indexes, and that those indexes have values, and it also expects the callback function to accept arguments in a specific order. Things aren't exactly mapped between the array and the callback function, the forEach function just passes each index and its corresponding value to the callback function in turn.


No comments:

Post a Comment

c++ - Does curly brackets matter for empty constructor?

Those brackets declare an empty, inline constructor. In that case, with them, the constructor does exist, it merely does nothing more than t...