A little while ago, Jonathan Cutrell opened an interesting issue about immediate-invoked function expressions (IIFEs) on our JavaScript style guide:
Could this:
https://gist.github.com/4121075
Be this?
https://gist.github.com/4121135
And of course the short answer is yes, it could be either. Crockford makes a good case for the parens on the inside:
When a function is to be invoked immediately, the entire invocation expression should be wrapped in parens so that it is clear that the value being produced is the result of the function and not the function itself.
javascript.crockford.com/code.html
If you don’t care about the return value of the IIFE, you can also write them like this:
https://gist.github.com/4121159
Let’s explore the two IIFE methods using parentheses a bit more.
https://gist.github.com/4121197
Both work the same. It starts to get interesting when one of the modules is missing a trailing semicolon:
https://gist.github.com/4121201
With a missing semicolon, each set of parens is trying to immediately-invoke the preceding expression. That would be the return value of the preceding IIFE.
https://gist.github.com/4121202
So the difference is when the TypeError happens. Let’s check out what the arguments are up to. Note thatconsole.log()
returns undefined
:
https://gist.github.com/4121217
<p>
</span></span>
</p>
<p>
<span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;">Now let's do that same example with the Crockford way:</span>
</p>
<p>
<span style="line-px;"><span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;"></p> <p>
<a class="https://gist.github.com/4121235">https://gist.github.com/4121235</a>
</p>
<p>
</span></span>
</p>
<p>
<span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;">But wait, there's no TypeError here...</span>
</p>
<p>
<span style="line-px;"><span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;"></p> <p>
<a class="https://gist.github.com/4121239">https://gist.github.com/4121239</a>
</p>
<p>
</span></span>
</p>
<p>
<span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;">There's no TypeError because of the returned function. The returned function that logs the arguments is then getting invoked with the return value of module2, which is </span><code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; px; font-family: Consolas, Liberation Mono, Courier, monospace; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; color: #333333;">undefined</code><span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;">.</span>
</p>
<p>
<span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;"> </span><span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif; line-px;">With that understanding, let's go back to the original example, where there was a TypeError:</span>
</p>
<p>
<span style="line-px;"><span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;"></p> <p>
<a class="https://gist.github.com/4121244">https://gist.github.com/4121244</a>
</p>
<p>
</span></span>
</p>
<p>
<span style="line-px;"> </span>
</p>
<p style="margin: 15px 0px; padding: 0px; border: 0px; color: #333333;">
<strong><span style="medium;">Conclusion</span></strong>
</p>
<p style="margin: 15px 0px; padding: 0px; border: 0px; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;">
The <code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; px; font-family: Consolas, Liberation Mono, Courier, monospace; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">(function{})();</code> and <code style="margin: 0px 2px; padding: 0px 5px; border: 1px solid #eaeaea; px; font-family: Consolas, Liberation Mono, Courier, monospace; background-color: #f8f8f8; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px;">(function(){}());</code> IIFEs can act differently in the missing semicolon situation.
</p>
<p style="margin: 15px 0px; padding: 0px; border: 0px; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;">
Use a tool to make sure modules aren't missing trailing semicolons when working on modules.
</p>
<p style="margin: 15px 0px; padding: 0px; border: 0px; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;">
To be extra safe add a leading semicolon to the IIFE:
</p>
<p style="margin: 15px 0px; padding: 0px; border: 0px; color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;">
<span style="color: #333333; font-family: Helvetica, arial, freesans, clean, sans-serif;"><p>
<a class="https://gist.github.com/4121262">https://gist.github.com/4121262</a>
</p></span>
</p>
<p>
Hope that helps!
</p>
0 Comments