Blogs

  • Browse Blogs
  • My Blog
  • My Updates

Tags Help

  • View as cloud  | list

Similar Blogs

photo

Beyond The Ye...

248 Entries |  Peter Presnell
Updated 
RatingsRatings 13     CommentsComments 396
photo

TexasSwede

109 Entries |  Karl-Henry Martinsso...
Updated 
No RatingsRatings 0     CommentsComments 94
photo

Erik Brooks

35 Entries |  Erik Brooks
Updated 
RatingsRatings 9     CommentsComments 92
photo

Lotus Nut

111 Entries |  Chris Whisonant
Updated 
RatingsRatings 23     CommentsComments 157
photo

Patrick Picar...

62 Entries |  Patrick Picard
Updated 
RatingsRatings 2     CommentsComments 112

Bookmarks

Yellow is the New Blog

Blog Authors:  Tim Tripcony  

Previous |  Main  | Next

revisiting closures

Tim Tripcony  |     |  Tags:  javascript  |  Comments (0)
I've occasionally mentioned the JavaScript concept of "closures", but recently it's come up in several conversations, so I wanted to revisit it in case any of you have been curious about what this is or why you should care.

Put simply, they're a complete departure from typical variable scope handling (unless you're used to Lisp or Perl). Consider, for example, the following LotusScript function:

Public Function getWidget (Byval widgetName As String) As Widget
 Dim localSomething As String
 Dim myWidget As New Widget(widgetName) 'Assume this class is defined elsewhere
 Let localSomething = "this is a pointless variable"
 Set getWidget = myWidget
End Function

Pretty straightforward: a new instance of some Widget class is constructed using the passed argument and returned from the function. A local String variable is declared and assigned a value, but it's completely unnecessary, because as soon as the function returns the new Widget object, any variables declared inside the function are garbage collected anyway. So if, for example, Widget contains a method that refers to the localSomething variable, that method will look for the variable within the class definition and, failing that, global variables... if none exists, expect an error.

Java adds another layer of garbage collection called block scope:

public Widget getWidget (String widgetName) {
 if (somethingIsTrue) { // assume a boolean defined elsewhere
  Widget myWidget = new Widget(widgetName);
 }
 return myWidget; // oops... NullPointerException
}

In this example, myWidget is actually local to the conditional (if) block: we can't refer to it outside of that block, because it's defined inside it. To refer to it after the block, we'd actually have to define it before the block, whether or not we plan to do anthing to it inside the block.

So what makes closures different? In JavaScript, an object returned from a function still has access to variables local to the function that returned it. "Whaaa?" Yes, the garbage collector knows not to destroy those variables until the object is destroyed, because it might want to refer to them later. For example:

var Widget = function(widgetName) {
 var localSomething = 'This may come in handy later.';
 return {
  displayLocal: function() {alert(localSomething);}
 };
};
new Widget().displayLocal(); // alerts the value of localSomething

In this case, an object is created that contains a single "public" method: displayLocal. This method can safely refer to the localSomething variable, because it's bound to that variable via closure. In essence, this allows JavaScript objects to contain "private" variables and methods: if we had defined any functions within the above function - but outside of the returned object - they could be called by the returned object... but not by other code outside of the function that contains them.

In other words, this allows JavaScript objects to be defined such that they behave more like class instances in other languages: they can contain public and private members. As such, in the above example, I "instantiate" a Widget via new... but worth mentioning is that I didn't need to: each time the above function is called, two new objects are created: a local String and an object containing a public method that can refer to that String even after the function that created both has returned. Hence, whether I include the new keyword or not, a new object with the same behavior template is created, and any locally defined objects bound to it by closure are new as well: a separate instance of localSomething is bound to each object created by calling this function. I tend to use new when calling functions that are structured this way to indicate (to myself and others maintaining my code) that the returned object behaves like a class instance, but the behavior is not dependent upon that convention.

One final syntactical nugget before discussing implications: tacking parentheses onto the example function's definition makes it behave something like a singleton:

var Widget = function(){
....
}();
Widget.displayLocal(); // we no longer need to call the function each time

In this case, the function is called immediately, so the variable Widget is assigned a pointer to the object that is returned from the function, not to the function itself. Widget IS the object. It has public methods bound to private data. For quite a while, I've preferred this approach to defining global singletons, because you don't have to call a function each time... you already have the object. But I'm finding that this tends to confuse people: they'll try to instantiate the object again, which causes the code to break, because Widget isn't a function, so treating it like a function returns an invalid result. In the end, of course, it's always best to keep global variables to a minimum; Yahoo recommends creating a single singleton that represents the entire application, and nesting objects appropriately within that space, and that's what I tend to do. This seems to mitigate the confusion, as most developers then grok that there's no need to construct new copies of the object; just "use" the object as constructed in-place, and customize it as needed.

So with all of that out of the way, why are closures actually useful? The same reason private members of a LotusScript class are useful:
  • Internal storage of variables that cannot be mucked with from outside the object
  • Minimizing global variables by associating groups of related data with a container object
  • Probably most importantly, manageable code through proper decomposition without convolution of the public API
That last point probably bears repeating: as an object's complexity increases over the development (and enhancement) of the application or framework, you certainly could choose to make every method public. "Information hiding" (at least, in my experience) is more about shielding other programmers from the complexity of the code than it is about protecting the code from other programmers. When you're writing integration APIs (like a web service), of course, the latter factor increases, but the former is still crucial: imagine a WSDL that defined 237 service methods (and I assure you, they do exist)... it'd be a nightmare to keep track of what the service can be used for. Now imagine a complex web app that includes a JavaScript object with that many public members. It's highly likely that most of those members are for the internal convenience of the object itself, both to avoid duplicating the same code within multiple functions and to decompose the operation of each into tasks that are small enough to be easily understood. Closures allow for precisely that: decompose each function into smaller private functions, tuck away properties like internal counters that don't necessarily need to be publicly visible, therefore keeping the public API robust enough to meet the application's needs but simple enough to interact with and maintain.

Quick tip: making your buttons fancy in XPages

Tim Tripcony  |     |  Tags:  xpages  |  Comments (0)
Thanks to the wonderful browser manufacturers whom we web developers all love so dearly, we don't have to settle for buttons that look alike regardless of which browser our users are using. The variations are even fairly predictable: in IE, buttons are blocky and gray, Firefox tries to blend in with your operating system theme (unless overridden in an extension), and - like everything else Apple does - Safari's buttons are cute, shiny, and round. And what's that other one? I always forget.

But... if you want to be boring and ensure that your buttons look (nearly) identical - but still attractive - across all major browsers, and you happen to be developing in XPages, it's easy. Assuming you're using the button control (as opposed to input tags via passthru), switch to the "All Properties" section and, under the "basics" category, set the value of "dojoType" to "dijit.form.Button", and "dojoUsage" to "enable". The button will now be magically rendered as a dijit (yes, Domino handles the necessary require statements for you automatically), so it will look reasonably modern and consistent across browsers.

Previous |  Main  | Next
Skip to main content link. Accesskey S
IBM Lotus Connections Help Tools About

Tags

A tag is a keyword that is used to categorize an entry. To view the entries with a particular tag, click a tag name or enter a tag in the box.
The tag cloud indicates the frequency of tag use. Popular tags appear darkest. The slider control adjusts how many tags are displayed in the tag cloud.