Monday, November 26, 2007

Named Parameters in Javascript Functions

Named Parameters with {}
Named parameters is a blessing. When you write Java, eclipse helps you to remember parameter order with auto-completes. But wouldn't it be nice to remember arguments by name rather than by index?


function friendToHtml(friend) {
html = "<span>"
html += "<h1>" + (friend.name || "Joe Schmoe") + "</h1>"
html += "<ul>"
html += "<li>Phone " + (friend.phone || "<i>Not listed</i>") + "</li>"
html += "<li>Email " + (friend.email || "<i>Not listed</i>") + "</li>"
html += "<li>Address " + (friend.address || "<i>Not listed</i>") + "</li>"
html += "</ul></span>"
return html;
}


friendToHtml({
name : 'Marcus',
address : '5500 S Shore Drive, Chicago IL',
email : 'narcvs@gmail.com',
phone : '1-800-javascript'
}) // -->
// <span><h1>Marcus</h1><ul>
// <li>Phone 1-800-javascript</li>
// <li>Email narcvs@gmail.com</li>
// <li>Address 5500 S Shore Drive, Chicago IL</li>
// </ul></span>


friendToHtml({
email : 'callMe@example.com'
}) // -->
// <span><h1>Joe Schmoe</h1><ul>
// <li>Phone <i>Not listed</i></li>
// <li>Email callMe@example.com</li>
// <li>Address <i>Not listed</i>
// </li></ul></span>


The Default Operator ||
Note that we did not have to specify the parameters in the correct order. Another advantage is that named parameters also allow for painless default value assignment. In fact, the || operator is also called the "default operator." For example, if name was not specified, just fall back to "Joe Schmoe."

...

html += "<h1>" + (friend.name || "Joe Schmoe") + "</h1>"

...


The Guard Check a ? b : c
Sometimes you might not be 100% sure that an object passed to your function was actually defined. Let's say that your friends sometimes have a list of favorite books (but not always), and that you want to include the first book on the list in the html description.

If the friend.books field is not specified and you try to access friend.books[0] an exception will be thrown. In order to avoid this you would usually write:

...

if (friend.books) {
html += "<li>Favorite book " + friend.books[0] + "</li>"
} else {
html += "<li>Favorite book <i>Not listed</i></li>")
}

...

But that's just ugly. Here is a one liner that checks that books have been defined, and otherwise defaults to another value

...

html += "<li>Favorite book " + ((friend.books && friend.books[0]) || "<i>Not listed</i>") + "</li>"

...
This way you first check that friend.books is defined. If it is not then default to Not listed

No comments: