I was just digging through some JavaScript code (Raphaël.js) and came across the following line (translated slightly):
Math.min.apply(0, x)
The reason is this:
Your input x
is an array
The signature of Math.min()
doesn't take arrays, only comma separated arguments
If you were using Function.prototype.call()
it would have almost the same signature, except the first argument is the this
context, i.e. who's "calling"
Math.min.call(context, num1, num2, num3)
The context
only matters when you refer to this
inside the function, e.g. most methods you can call on an array: Array.prototype.<method>
would refer to this
(the array to the left of the 'dot') inside the method.
Function.prototype.apply()
is very similar to .call()
, only that instead of taking comma-separated arguments, it now takes an array after the context
.
Function.prototype.call(context, arg1, arg2, arg3)
Function.prototype.apply(context, [arg1, arg2, arg3])
The 0
or null
that you put in as the first argument is just a place shifter.
Here is an example where we can get the MAX and MIN timezone offsets for the given year for a timezone. It returns the two changes for the year to account for DST and ST. (i.e. ST = 300 an DST = 360 for the timezone in question).
var arr = [];
for (var i = 0; i < 365; i++) {
var d = new Date();
d.setDate(i);
var newoffset = d.getTimezoneOffset();
arr.push(newoffset);
}
var DST = Math.min.apply(null, arr);
var nonDST = Math.max.apply(null, arr);
tw.local.stInt = DST
tw.local.edInt = nonDST
The proper and less confusing way to call this is: Math.min.apply(null, array)
If parameter is unused setting it to null makes code more readable than setting it to 0 or Math
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
I realized the answer as I was posting my own question: This is the most succinct way of taking the min of an array x
in JavaScript. The first argument is totally arbitrary; I find the 0 confusing because the code intuitively means "Take the min of 0 and x," which is absolutely not the case. Using the Math object makes more sense for human-readability, but the Raphael.js authors are obsessed with minification and 0 is three bytes shorter.
See http://ejohn.org/blog/fast-javascript-maxmin/
For readability's sake, I'd strongly urge people to stop doing this and instead define a function along the lines of
function arrayMin(arr) { return Math.min.apply(Math, arr); };