1
\$\begingroup\$

I want to extend an app object with a widget that initializes itself immediately.

Immediately-Invoked Function Expression:

var app = {};
(function() {
 app.widget = {
 init: function() {
 return true;
 }
 };
 app.widget.init();
}());

Immediately-Invoked Object Expression:

var app = {};
({
 init: function() {
 app.widget = this;
 return true;
 }
}.init());

Please take a look: http://jsperf.com/iife-vs-iioe

Caridorc
28.1k7 gold badges54 silver badges137 bronze badges
asked Apr 16, 2013 at 11:53
\$\endgroup\$
4
  • 3
    \$\begingroup\$ It's better if you actually put the code here. If jsPerf was down, this question won't have any future value. \$\endgroup\$ Commented Apr 16, 2013 at 11:55
  • \$\begingroup\$ Quick tip: Change the first line in either example to window.app = window.app || {}; (I'm guessing app is a global). That way, you'll avoid overwriting it if you or someone else defines it elsewhere (technically, you should do a full check for typeof window.app === 'undefined' but the default operator covers most cases and conveys the intention well) \$\endgroup\$ Commented Apr 16, 2013 at 15:55
  • \$\begingroup\$ @Flambino: You are right. window.app is the better way to handle conflicts and overwriting. In this example code I would like to clear out the basic idea between iife vs. iioe. \$\endgroup\$ Commented Apr 17, 2013 at 7:44
  • \$\begingroup\$ @RonnySpringer Understood. I just pointed it out just in case. As for your actual question: I'd stick to using an IIFE, mostly because it is the most common, well-known pattern, and because you get an isolated context for your code (that context creation is probably partly why it's slower than the IIOE) \$\endgroup\$ Commented Apr 17, 2013 at 9:53

1 Answer 1

1
\$\begingroup\$

Code is not just about performance. You have to check for maintainability, scalability and readability as well.

With regards to the way code is written, I'd favor the first method because it's the module pattern and is a common convention. The second one is too full of brackets and the object notation, though flexible, is nasty especially when you forget the commas.

For extendability, I suggest you build a base set of helper functions to facilitate module loading and phase handling. Here are potential events that you might want to hook on events:

  • when the DOM is ready (DomContentLoaded)
  • when everything is loaded (window.onload)
  • when the page is unloading (window.onunload and onbeforeunload)
  • when the widget is loaded into the library
  • when the widget is unloaded/removed
  • when the widget is first run (init)
  • and so on...

Also, I suggest the following style of extension since:

  • It creates a single local scope for your widget to operate and share. You have the so called "private sandbox".
  • Objects are provided as an interface to attach stuff like public methods/properties, handlers and stuff. Whatever attached will be collected by your framework, sorted and executed accordingly.
  • It's simple and readable!

Here's a sample of a widget:

//assumung app is your framework namespace
app.addWidget('WeatherWidget',function(handles,publicStuff){
 //your local scope
 var foo = 'bar';
 function baz(){console.log('bam');}
 //handles and public are your interfaces
 //in this example, handles will be used to collect your event handlers
 handles.init = function(){/*run on init*/};
 handles.documentReady = function{/*run on DOM ready*/};
 publicStuff.getBar = function(){return foo;}
});
answered Apr 16, 2013 at 12:37
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.