Showing posts with label JavaScript. Show all posts
Showing posts with label JavaScript. Show all posts

Saturday, January 4, 2014

The JavaScript Module Pattern


It allows private members that can be used to maintain state using closure, and exposing only public members. So only a public API is exposed, keeping everything within the closure (nested function using the private variables) as private. This pattern is similar to an IIFE, save that an object is returned instead of result of a function execution.

Note that JavaScript don't have getters and setters or access modifiers, so we use closures and function scopes to simulate private members and maintain state inside a module.

//Shopping Cart Module
var shoppingCart = (function(){
      var cart= [];  //private
      
      //public API
      return {
            addItem: function(value) {
                    cart.push(value);
            },
            itemCount: function() {
                   return cart.length;
           },
           totalPrice: function() {
                    var i = this.itemCount(),
                               p = 0;

                    while(i--) {
                          p += cart[i].price;
                    }
                   return p;
           }
     }      
}());

The shopping cart module is self-contained in a global object called shoppingCart. The cart array is private and only exists within the module's closure. The addItem and itemCount methods can access the cart array as it is within the scope of the outer function.

The module returns an object that gets assigned to shoppingCart as it is immediately invoked. this way we can interact with the shoppingCart object as follows:

//call an API method of the module
shoppingCart.addItem({item:'Effective JavaScript',price:8.99});

//this will work
console.log(shoppingCart.itemCount());
console.log(shoppingCart.totalPrice());

//this will return undefined
console.log(shoppingCart.cart);

Notice that the methods defined in the shoppingCart module have been effectively namespaced with shoppingCart and "avoids" global collisions. Of course, the issue of global variable declaration still remains if we have another global variable called shoppingCart declared.

Also, an object literal can be used to define a module by just assigning it to a variable! This is sufficient if we don't need to maintain state or require private variables. Object literals cannot instantiate using the new operator and we can simply start using the object declared as an instance.

Why use Modules in JavaScript?


The short answer : Mimic classes and code organization!

It mimics classes for code encapsulation - not inheritence per se. 
Javascript has prototypal inheritence, where we can dynamically add members to the prototype property of the class/object we define. The members added are shared across all instances of classes created AFTER we have defined the prototype members - akin to static members. The members defined if any, in the class(function) itself belong to individual instances with reference to the "this" keyword.

A module can be a distinct unit of functionality, like a navigation module, a filter module, an email notification module etc. We can think of it as a JavaScript equivalent of a .NET component. Decomposing your code into modules helps maintainability of your application by keeping them loosely coupled and removing dependencies where possible.
  • Allows encapsulation of private members giving it an object-oriented flavor
  • Avoids function name clashes with other parts of the JavaScript code
  • So helps in code organization
  • By immediately invoking the function expression, returns only the object container or function with the values of the private members remembered through closure. So returns only a public API in the forma of an object, keeping everything else private using closure.
  • Very similar to IIFE, except an object is returned, rather than a function.
Sample module to avoid global scope contamination using Closure and the Revealing Module Pattern:

var module = (function () {
   var privateVariable; //private member

  /* a private function uses the private variable in a closure .. (read nested function) 
      Allows the private member to be declared (and initialized) only once and exposed indirectly
      without  polluting the global namespace */
   var privateFunction = function (x) {
         /* uses the private variable */
        };
  
   /* Another private function - just named public here because we are going to expose it outside
      the module defintion */
   var publicFunction = function () {
         privateFunction (); /* Can call the private function */
   };

   /* returns an object literal */    return {
      PublicFunction : publicFunction  /* exposed as a public function here! */
  } 
}()); /* Outer function is immediately executed here */

/* Note that this is a Singleton pattern as it is immediately executed here, and we cannot create
   multiple instances of this module */

In Modern JavaScript design patterns, these 4 object-oriented design patterns

  1. Prototype Pattern
  2. Module Pattern
  3. Revealing Module Pattern
  4. Revealing Prototype Pattern

can be implemented using

  • AMD - allows modules to be loaded asynchronously without care for script loading order
  • CommonJS module - Module dependencies have to worry about the order while loading script in browser
  • ECMAScript Harmony - the next version of JavaScript!

Thursday, September 5, 2013

JavaScript close child window without closing parent

When using Javascript to close a child window used say as a pop-up window from an asp.net page, one of the issues we may run into is while trying to close the child window using a html input button/link etc.

Using window.close() would try to close not just the child window but the parent as well, along with the accompanying IE alert dialog that ask you that the current window is trying to close all the windows.

One way to get around this issue is by assigning the self property to the child window as shown below. That way when it calls the close() routine, Javascript understands it wants to close itself - this is the classic example of the "this" Javascript conundrum.

function OpenPopup()
{
   window.open('url','name','options');
   window.opener = self;
   window.close();
}


Another technique I have used when using an asp.net hyperlink control to open a child window from within a grid is to

  • set the hyperlink target to null
  • use javascript:void(...)
  • give an empty string for the name parameter and then
  • call self.close() from the child window

Example in the code behind routine for NavigateUrl of the parent window that has the grid and hyperlink -

hlnk.Target = null;
return "javascript:void(window.open('childPopup.aspx?track=" + trackNumber + "','','height=500,width=800, left='+((screen.width - 800) / 2)+', top='+((screen.height - 500) / 2)+', toolbar=no,menubar=no,status=no,scrollbars=yes,resizable=no'))";

Notice the use of the special syntax for top and left to center the child window in the middle of the screen.
This is so that Javascript evaluates the math operation and use that to assign it as the left and top key values.Otherwise Javascript won't evaluate the expression if used simply as left=(screen.width - 800)/2, and simply assign (screen.width - 800)/2 as a string!!