Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Solving this requires knowledge of two JavaScript concepts.</p> <p>The first is the special <a href="https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments" rel="nofollow noreferrer"><code>arguments</code></a> local variable that can be used to access the function arguments without knowing their name and it works like an Array. However, <code>arguments</code> is <em>not</em> an <code>Array</code>, but is "array like" -- having properties named <code>0..n-1</code>, where <code>n</code> is the number of arguments to the function and a <code>length</code> property -- object. A simple demonstration usage might be:</p> <pre><code>function f (a) { // can include names still, if desired // arguments instanceof Array -&gt; false (exceptions to this?) var firstArg = arguments[0] // a === firstArg -&gt; always true // iterate all arguments, just as if it were an Array: for (var i = 0; i &lt; arguments.length; i++) { alert(i + " : " + arguments[i]) } } f("a","b","c") </code></pre> <p>The second feature is <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply" rel="nofollow noreferrer"><code>Function.apply</code></a> which will invoke a function with a specific context (<code>this</code> when it is called) with arguments that result from the <em>expansion</em> of an "array like" object. <strong>But see <sup>1</sup></strong>.</p> <p>Thus, putting it together:</p> <pre><code>function fireStartedEvent() { for(var i = 0; i &lt; startedListeners.length; i++) { // jQuery will often pass in "cute" things, such as a element clicked // as the context. here we just pass through the current context, `this`, // as well as the arguments we received. var arg = Array.prototype.slice.call(arguments) startedListeners[i].apply(this, args) } } </code></pre> <hr> <p><sup>1</sup> While the ECMAScript specification only calls for an "array like" object, <code>Function.apply</code> <em>does not</em> universally work with an "array like" object and a number of common implementations <em>require</em> a proper <code>Array</code> object. The warning from the <code>Function.apply</code> link:</p> <blockquote> <p>Note: <strong>Most browsers, including <em>Chrome 14</em> and <em>Internet Explorer 9</em>, still do not accept array like objects and will throw an exception [if a non-Array object is passed].</strong> [FireFox was fixed in version 4.]</p> </blockquote> <p>Thankfully, there is a relatively simply idiom to turn an "array like" object into an <code>Array</code> (which is ironic because <code>Array.slice</code> <em>does</em> universally work with an "array like" object):</p> <pre><code>var args = Array.prototype.slice.call(arguments); </code></pre> <p>(And then <code>args</code> can be universally used in be used in <code>Function.apply</code>.)</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload