domenica 7 aprile 2013

Another 10 Interesting JavaScript Features

I previously posted about 10 Interesting JavaScript Features. Here’s ten more JavaScript features that I’ve recently found interesting.

1. Dynamically call object methods

Javascript objects can contain functions as object members. Object members can be referenced using square bracket [] notation. Combining these ideas together we can dynamically call object methods:

var foo = {
 one: function() { console.log("one") },
 two: function() { console.log("two") }
};
 
var ok = true;
var result = foo[ok ? "one" : "two"]();
 
console.log( result ); // Prints "one"

2. Multi line strings

You can create multi-line strings in JavaScript by terminating lines that should be continued with a backslash:

var s = "Goodbye \
cruel \
world";
 
console.log( s === "Goodbye cruel world" ); // true

3. Recursion in anonymous functions

JavaScript allows functions to be created that have no names. These are called anonymous functions. A recursive function is one that calls itself, but how does a function call itself if it has no name?
First let’s consider a small program that applies a factorial function to numbers in an array.

// Our recursive factorial function
var factorial = function(n) {
    return n<=1 ? 1 : n * factorial(n-1);
};
 
// Function that applies a function to each element of the array
var applyTo = function(array,fn) {
 var i=0, len=0;
 for (i=0, len=array.length; i<len; i++) {
  array[i] = fn( array[i] );
 }
 return array;
};
 
// Test our function
var result = applyTo( [2,4,6], factorial );
 
console.log( result ); // Prints [2, 24, 720]
 
Rather that defining the factorial function separately, we can define it inline as a parameter to the applyTo() function call.

var result = applyTo([2,4,6], 
                     function(n) {
                         return n<=1 ? 1 : n * ???WhatGoesHere???(n-1);
                     }
                 );
 
Previously, JavaScript allowed us to replace the ???WhatGoesHere??? part with arguments.callee, which was a reference to the current function.

var result = applyTo([2,4,6], 
                     function(n) {
                         return n<=1 ? 1 : n * arguments.callee(n-1);
                     }
                 );
 
This method still works in modern browsers but has been deprecated, so remember what it means but don’t use it.
The new method allows us to name our inline functions.

var result = applyTo([2,4,6], 
                     function fact(n) {
                         return n<=1 ? 1 : n * fact(n-1);
                     }
                 );

4. Short cuts with ‘or’ and ‘and’ operators

When you or together several variables in a statement, JavaScript will return first ‘truthy’ value it finds (see previous post about truthy values). This is useful when you want to use a default value if an existing variable is undefined.

// Create an empty person object with no properties
var person = {};
 
// person.firstName is undefined, so it returns 'unknown'
var name = person.firstName || 'unknown';
 
// Prints 'unknown'
console.log(name);
 
In contrast, the and operator returns the last element, but only if all of the expressions are truthy, else it returns undefined.

var o = {};
o.x = 1;
o.y = 2;
o.z = 3;
 
var n = o.x && o.y && o.z;
 
// Prints 3
console.log(n);

5. A note about ‘undefined’

It turns out that undefined is not a JavaScript keyword, instead undefined is a global variable, which in browsers is defined as window.undefined.
It is not uncommon to see code that tests if a variable is undefined like this:

if (someObject.x === undefined) {
    // do something
}
 
Which is the same as writing

if (someObject.x === window.undefined) {
    // do something
}
 
If by some chance your window.undefined variable is modified then checks for undefined like this will fail. No conscientious developer would ever do this intentionally, but it may happen by accident causing hard to find bugs, like this:

var o = {};
window[o.name] = 'unknown'; // BLAM!, window.undefined is now a string
 
A better way to test for undefined is to use the typeof operator. Typeof an undefined variable will always return the string ‘undefined’.

// Good way to test for undefined
if (typeof someObject.x === 'undefined') {
    // do something
}

6. Return statement

The return statement needs it’s value to be on the same line as the return keyword. This may cause problem depending on your coding style. For example

// This is ok
return x;
 
// This returns undefined
return
    x;
 
// This is ok
return {
    result:'success'
}
 
// This returns undefined
return
{
    result:'success'
}
 
This behaviour is due to JavaScript’s automatic semicolon insertion.

7. Length of a function

JavaScript functions have a length property that provides a count of the number of arguments the function expects.

function foo(a,b,c) {
}
 
console.log( foo.length ); // Prints 3

8. The plus operator

The plus operator can be used to easily convert anything into a number by simply prefixing the value with “+”.

console.log( +"0xFF" );  // 255
console.log( +"010" );   // 10 
console.log( +null );    // 0
console.log( +true );    // 1
console.log( +false );   // 0
 
This is actually a just a nice shortcut for using the Number() function.

9. Object property names can be any string

JavaScript object members can have any string as their name.

var o = {
    "What the!": 'a',
    "Hash": 'b',
    "*****": 'c'
};
 
for (var key in o) {
    console.log( key );
}
Which prints:
What the!
Hash
*****

10. The ‘debugger’ statement

In the past we were limited to using alert() statements to debug our JavaScript. After that we were rescued with the much more sane console.log(). Things have come a long way and we now have solid line debugging available in modern browsers.
However, there is one addition to our debugging arsenal which I’ve found particularly invaluable when debugging JavaScript in Internet Explorer; the debugger statement.
When you add the debugger statement to your code the browser will stop execution and open the debugging environment ready for you to continue stepping through your code.
This is moderately useful on Chrome, Firefox and Safari but I have found essential for debugging IE.
Note that within IE, this statement only works in IE7 and above and you need to first start the debug mode.
OK, so that’s 10 features, but just one more thing to wrap up which is not really a JavaScript feature.

JavaScript Coding Coventions

If you’re not following a JavaScript coding convention then here are a couple to get you started:
This entry was posted in JavaScript and tagged . Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.

Nessun commento:

Posta un commento