JavaScript for the C# Developer Part 3 – Functions

Next: JavaScript Types

In the previous post I wrote about the basic scoping rules in JavaScript. There is more to say on that subject but first you need to understand the basics of functions.

The way JavaScript uses functions is very different from the way C# uses functions. JavaScript is a multi-purpose language that allows a variety of programming styles: procedural, object-oriented, and functional. This is because functions are incredibly flexible. This is one of the reasons I compare JavaScript to a sharp piece of metal with no safety features and a reason some people dislike working with JavaScript (especially other people’s JavaScript). The flexibility of functions allows syntax that is very confusing when approached from a strictly object oriented language like C# where functions are generally encountered only as members of classes.

In this post I will ignore functions as they relate to objects and save that discussion for later. For now I’ll focus on functions as procedures and as variables. As an aside, one of the best blog posts I’ve ever read on any subject is Steve Yegge’s incredible Execution in the Kingdom of Nouns. It is written as a criticism of Java, but it applies to C# as well. If you feel like you must have classes in order to write good code, you might want to read that post before continuing to open your mind to the alternative style that JavaScript supports (but does not enforce as it also has objects) before continuing.

Functions can Contain Functions

In the previous post I showed several mistakes that cause implied or unintended global variables. Nested functions provide a mechanism to prevent this and protect variables from being stomped by other script. Consider the following example (http://jsfiddle.net/DougWare/85MgV/).


In this example we have two functions, foo() and foo2(), each of which contain a variable named x and a function named bar(). If you execute the code you will see that foo and foo2 do not interfere with each other and that they neatly encapsulate their contents.

Functions can be Anonymous

An anonymous function is a function that has no name. If you’ve used jQuery you have almost certainly created anonymous functions most commonly with $(document).ready().


In this example the highlighted portion is an anonymous function that is passed as an argument to the ready() function which executes it when the document is ready.

Functions are First Class Types

As you can see above, the anonymous function acts like a variable. That’s because it is a variable and its type is function. You can see this by evaluating an anonymous function with JavaScript’s typeof() function. (http://jsfiddle.net/DougWare/k7Bsq/)


I can rewrite the example with an actual variable to get the same result. (http://jsfiddle.net/DougWare/BCQrk/)


Function Statements and Function Expressions

The function keyword actually plays two roles. In the first example the function statement defined the functions foo() and foo2(). An expression is an operation that is evaluated at runtime and yields a result. In the examples where the function is assigned to a variable or passed as an argument function acts as an expression. The difference is very subtle but important because function statements are hoisted by the JavaScript runtime to the top of the call stack prior to execution, but expressions are evaluated during execution in place. This is illustrated in the following example. (http://jsfiddle.net/DougWare/XMbUL/)


When this script runs the alert Statement appears and then a runtime error occurs. If you just run this in JSFiddle the effect is that the second alert doesn’t display. If you use a debugger you will see the error.


nonHoistedExpression is undefined because the function expression is below the attempted use of the variable!

Immediately Executed Function Expressions

The first example in this post works but is inelegant when we consider a script which we want to execute but which contains variables which we want to protect (and we always want to protect our variables). Since functions are first class types, functions can be anonymous, and function is an expression, it is possible to combine these concepts to create an immediately executed function expression. Consider this simple example. (http://jsfiddle.net/DougWare/8eC3p/)


In this example the anonymous function is wrapped by parentheses and followed with another set of parentheses that contains the function’s arguments (if any).

This means that we can rewrite the first example as follows. (http://jsfiddle.net/DougWare/QELHB/)


Using an Immediately Executed Function Expression to Prevent Collisions

The previous example protects our code’s variables and functions from colliding with other code, but it is also commonly used to improve the safety of frameworks like jQuery. The jQuery library maps the variable $ to the jQuery() function to as shorthand. It does so to help keep scripts that use jQuery as small as possible. However, jQuery is by no means the only library that uses $ as shorthand ($ is a legal variable name). Therefore, jQuery includes the noConflict() function which stops this mapping to prevent collisions. However, using this by itself means your script files will be bigger because you have to spell out jQuery everywhere instead of using the shorter variable $.

Immediately executed function expressions are commonly used to prevent this conflict globally while preserving $ for scripts that desire as shorthand for jQuery. For example: (http://jsfiddle.net/DougWare/4CxQw/)


Hopefully at this point you understand how you can use functions to manage scope and prevent collisions caused by global variables. There is more to cover on functions, but before that I’ll return to variables in the next post and talk about data types.

–Doug

Author: Doug Ware
(I’m trying out Google’s verified author system)

 
 

   

Author: Doug Ware