JavaScript Shortcuts
JavaScript has many useful features that can decrease the amount of code you have to write. This post goes over some of my favorite shortcuts.
Using Commas To Avoid Curly Braces
The most common use of commas I've seen in JavaScript has been separating arguments and declaring multiple variables. It turns out you can actually use them in other places as well.
One useful way to use this approach is when you need to change multiple variables when a certain condition is met. By using commas you can avoid using a pair of curly braces to wrap the assignments.
In the example below we have a flattened array of values for a grid. The variables x
and y
are used to keep track of the current coordinates as we loop though the array.
//some information to display var perRow = 3; var grid = [0,0,1,0,1,0,1,0,0]; //monitor the coordinates to draw at var x = 0, y = 0; for(var point in grid) { draw(grid[point], x, y); //manage the position variables without //needing a set of curly braces // if reaching row limit? // - reset X to zero // - move down the next row if (++x == perRow) x = 0, y++; }
You'll notice on that you can avoid the use of curly braces and instead use a comma to set both the x
and y
values as part of the same if
statement. It certainly isn't a very big gain but it does reduce the amount of code by a few characters.
Use Logical Operators To Provide Defaults
One of the strengths of JavaScript is that you can pass as many (or as few) arguments as you like into any method. Unforunately, this can also make it difficult to be certain that every argument has been provided.
JavaScript has many interesting ways to evaluate true
and false
. Most values will evaluate as true
when they are present whereas null
evaluates as false
. We can use this to help determine which values need a default value assigned.
//create a message for showing var showError = function(error, title, type) { //if the parameter is not known then the //next value will be used dialog.show( error || window.error || "An unexpected error occurred.", title || "Error", type || dialog.styles.error ); }
In this sample, if an argument isn't provided JavaScript will skip it and attempt to use the next value. Eventually, if nothing usable is found the code will simply use the last value which will be the default value. This avoids using a bunch of if/then
statements to find a value to use.
This approach works well when you're checking for missing (null
) values, however, this doesn't work well when the value provided evaluates as false
even when set.
//examples where 'or' could get you into trouble 0 || 100 // 100 "" || "green" // 'green' NaN || -1 // -1 false || true // true
Each example above has a value provided but will still evaluate as false
! This results in the provided value being ignored and the default value being used instead. In those instances you're probably better off using a ternary operator to find the correct default.
//using a ternary instead of 'or' typeof value == "number" ? value : 100 // value if is a number typeof value == "string" ? value : "green" // value if is a string isNan(value) ? value : -1 // value if is NaN value === false ? false : true // false is set to 'false'
Additional Information For Anonymous Functions
Being able to pass functions
around as arguments one of the best features of JavaScript (or any language that allows passing methods for that matter).
However, this can be problematic when you need to provide more than a couple arguments to the anonymous function. The example below is a simple method that loops through a collection that provides additional loop information as part of the method call.
//action requires too many arguments!! var each = function(collection, action) { for(var item in collection) { var value = collection[item]; //... action(value, index, key, even, odd, total, first, last, remaining); } };
In order to have access to the values provided we must make sure to include the parameter as part of the anonymous function which can be annoying if all you really need is one of the last values.
Fortunately, we can use the call
or apply
methods to change the context of the this
object within the anonymous function.
//simple loop method with additional information //available for each record var each = function(collection, action) { //get the total records to use var count = 0; if (collection instanceof Array) count = collection.length; else for(var item in collection) count++; //start looping through the collection var index = 0; for(var item in collection) { var value = collection[item] var detail = { index: index, key: item, even: index % 2 == 0, odd: index % 2 != 0, total: count, first: index == 0, last: index == (count - 1), remaining: (count - 1) - index }; //use 'call' to invoke the action and use the //first parameter to specify what 'this' is in //the method if (action.call(detail, value) === false) break; //or return index++; } }; //using the each function. \ //the 'this' object is the same as the 'details' //object created on line 14 each(records, function(record) { //the 'record' argument is from the collection var row = $("<li/>").text(record.name); //'this' has additional information about the loop if (this.even) row.addClass("alt-row"); if (this.first) row.addClass("header"); });
By changing the context of this
we are able to provide much more information to the anonymous function without needing to include a slew of unnecessary arguments.
April 10, 2011
JavaScript Shortcuts
Samples and explanations of helpful shortcuts to use when writing JavaScript.