Sunday, November 22, 2009

Javascript: Finding Closure While Calculating UPS Dimensional Weight

It’s been quite a long time since my last post, "so many obligations, so little time".

Today I wanted to put something up here that could help others with the concept of the JavaScript closure.

As I researched the net, I found many great examples but none seemed to be viable to real world applications.

In this small example I will use the concept of closure to find the dimensional weight of an item that is going to ship via UPS. Please note this is not an all inclusive solution; as UPS presents many business rules in how they estimate shipping. (some of which are not even public).

Say we have a package that weights 1lb but the cubic weight (length x width x height) exceeds 5,184 cubic inches. UPS is not willing to ship your package at the 1lb rate - if they did they would probably take a loss on the item. Instead they have a formula on their site to help you arrive at the correct dimensional size.


L x W x H / 194


In applying the concept of closure we can use the following to calculate our true dimensional weight:
	function dimensionWt (l, w, h){
		var cubicWt = l * w * h;
		var finalWt;
		var wt = function(){
			if ( cubicWt > 5184){
				finalWt = cubicWt/ 194;
				return finalWt;
			}else{
				return cubicWt;		
					
		}
	}	
		return wt();
			
}

document.write(dimensionWt(25, 55, 50));
// result 354.3814432989691

Basically what we are doing here is creating a JavaScript function and putting another function inside of it - to create a closure. With this closure we are able to to hide the inner function wt(). Now any direct attempts we try to call the function wt() will not be successful - making our wt() function private.

What does the code do?

First we declare our outer function dimensionWt and give it three parameters. From here we create two variables to work with the inner function. The cubicWt variable contains the basic multiplication for the arguments we will pass, later, when calling the function. i.e. dimensionWt(25, 55, 50);

Next we use the wt variable to hold our inner function that checks the cubicWt to see if it is greater than 5,184. If it is greater we implement our L x W x H / 194 formula. If it is not then we return the the result of our first calculation var cubicWt = l * w * h;.

Some cleaning up

When first calling our function dimensionWt() with the arguments 25, 55, & 50, our code returns the messy result of 354.3814432989691. While this may work in some instances we really would like to clean this up a bit and return a more rounded number.

Since the code sample represents a small portion of code and will definitely need more to complete what ever project we are working on. We are going to augment JavaScript's built in Number object to create a reusable method - toInteger(). Now if we need to round any other numbers in our project - we simply have to call the toInteger() method to do our grunt work.

To augment the Number object we add the following:

  Number.prototype.toInteger = function () {
      	return Math[this < 0 ? 'ceiling' : 'floor'](this);

};
      		
      	function dimensionWt (l, w, h){
				var cubicWt = l * w * h;
				var finalWt;
				var wt = function(){
					if ( cubicWt > 5184){
						finalWt = cubicWt/ 194;
						return finalWt;
			}else{
				return cubicWt;		
					
		}
	}	
		return wt();
			
}
document.write(dimensionWt(25, 55, 50).toInteger());
// result 354 


Why would we want to create a closure?
In the most basic sense we are attempting to make methods or functions private in our implementation to avoid conflicts or unauthorized access. This paves the way for us to create more robust JavaScript Objects that can contain both private and public methods that can be used in various ways such as creating a JavaScript library.

Labels:

0 Comments:

Post a Comment

Links to this post:

Create a Link

<< Home