Sometimes I see JavaScript that is written with an argument provided that already has a set value or is an object with methods. Take this jQuery example for instance:
Let's take a look at $.each
for the example:
each: function (obj, callback, args) {
var value,
i = 0,
length = obj.length,
isArray = isArraylike(obj);
if (args) {
if (isArray) {
for (; i < length; i++) {
value = callback.apply(obj[i], args);
if (value === false) {
break;
}
}
} else {
for (i in obj) {
value = callback.apply(obj[i], args);
if (value === false) {
break;
}
}
}
// A special, fast, case for the most common use of each
} else {
if (isArray) {
for (; i < length; i++) {
value = callback.call(obj[i], i, obj[i]);
if (value === false) {
break;
}
}
} else {
for (i in obj) {
value = callback.call(obj[i], i, obj[i]);
if (value === false) {
break;
}
}
}
}
return obj;
}
This gets called from
$(".selector").children().each(function(i) {
console.log(i);
});
like:
return $.each.call(this, callback /* this is your function */, args /* which is an additional thing people rarely use*/ )
This is the line (in the first block) you want to look at
callback.call(obj[i], i, obj[i]);
It's calling the callback, and passing the object as the context – this is why you can use this
in the loop. Then the iteration i
and then the same object as the context are both sent as arguments to the callback. It's a little bit like magic; until you look at the source code.