Solving this requires knowledge of two JavaScript concepts.
The first is a special arguments local variable that can be used to access function arguments without knowing their name, and works like an array. However, arguments not Array , but it is "array like" - it has properties with the name 0..n-1 , where n is the number of function arguments and the length property object. A simple use of the demo could be:
function f (a) { // can include names still, if desired // arguments instanceof Array -> false (exceptions to this?) var firstArg = arguments[0] // a === firstArg -> always true // iterate all arguments, just as if it were an Array: for (var i = 0; i < arguments.length; i++) { alert(i + " : " + arguments[i]) } } f("a","b","c")
The second feature is Function.apply , which will call a function with a specific context ( this when it is called) with arguments that arise due to the expansion of an object of type array. But see 1 .
Thus, connecting it:
function fireStartedEvent() { for(var i = 0; i < startedListeners.length; i++) {
1 While the ECMAScript specification calls only an array object, Function.apply does not work everywhere with an array object, and a number of common implementations require a proper Array object. Warning from Function.apply link:
Note. Most browsers, including Chrome 14 and Internet Explorer 9, still do not accept array-type objects and throw an exception [if the object is passed without an array]. [FireFox has been fixed in version 4.]
Fortunately, there is a relatively simple idiom to turn an array object into an Array (which is ironic because Array.slice works everywhere with an object of type array):
var args = Array.prototype.slice.call(arguments);
(And then args can be used universally in Function.apply .)
user166390
source share