Functional JavaScript: Harnessing the power of the Function Object | 2 | WebReference

Functional JavaScript: Harnessing the power of the Function Object | 2

[previous] [next]

Functional JavaScript: Harnessing the power of the Function Object [con't]

Function Scope Primer

Used properly, function scope, like any variable, can enhance security and protect variables from being changed unintentionally. Conversely, misunderstanding the rules of scoping in JavaScript, and you could have some really cryptic and evasive bugs on your hands! Any functions defined at the <SCRIPT> level are global, and are accessible to every function, object and sub-function, regardless of their location in the code. Functions defined inside another function are trickier because the scope depends on how we define the inner function. At the beginning of the article we saw two ways of defining a function: var fn = function() {} and function fn() {}. There are a couple more options that we haven't seen yet. The last one, using the Function() constructor, doesn't affect scoping, so we'll leave that for later. It's the fn = function() {} syntax that can cause trouble. Whereas both the methods described earlier will create private variables when defined within another function, dropping the var keyword will always result in the creation of a global function, no matter where it's defined. The cause of this quirky behavior is that the var keyword is optional. Omitting it will cause the scripting engine to create the variable and add it to the global window object. Ergo: the var identifier is important! The following code snippet demonstrates the finer points of function scoping:

What is Lambda?

The concept of using a function as an argument in a function call is called lambda. Lambda derives from Lambda calculus and is a formal system designed to investigate function definition, function application and recursion. Developed in the 1930's, Lambda has emerged as a useful tool in the investigation of problems in computability or recursion theory, and forms the basis for Functional Programming. Functional programs are stateless and deal exclusively with functions that accept and return data (including other functions), but they produce no side effects in 'state' and make no alterations to incoming data.

The Function Object

It's important to keep in mind that a function in JavaScript isn't just a variable type, but a full-fledged object. In fact, all native JavaScript data types have equivalent objects, which store their properties and methods. For instance, when we create a string using the following syntax: var aString = "This is a string.", a String object is automatically created behind the scenes. This allows us to check its length using aString.length or call a method such as aString.split(', '); on it. In addition to having properties and methods, each object has at least one constructor. In the case of a String, we could also create one in the following manner: var myString = new String("This is a string object").

The Function object also has a constructor: new Function(string arguments, string body). Here's how we would create the testFor() function via the constructor:

The arguments parameter must consist of a comma-delimited list of valid JavaScript identifiers. In this case there's only one argument called "fn." The body is also a string containing all of the function code contained within the function block's opening and closing curly braces ({}).

Generally, using the Function's constructor to define functions should be kept to a minimum because it's generally slower than using one of the means that we discussed previously. Still, there are times where it may be appropriate to create one on the fly. We'll be looking at just such a situation in the "Self Invoking Function" section.

Function Properties

arguments: An array of all the arguments passed to a function.

arguments.callee: Returns a reference to the current function. Can only be used within the body of a function.
arguments.length: Returns the number of arguments passed to a function.

constructor: Specifies the function that creates an object's prototype. It's a direct reference to the function itself.

length: Specifies the number of arguments expected by a function. It's external to the function and not the same as the arguments.length property, which specifies the number of arguments actually passed to a function.

prototype: A value from which all instances of an object are constructed, and which also allows you to add other properties and methods to an object.

Function Methods

apply: Allows you to pass function arguments and the this pointer to another function.

call: Allows you to call a method within a different context.

toSource/toString/valueOf: All three methods return a string representing the source code of the function. They override their respective Object methods.

The following code uses the arguments.length and Function.length properties to compare the number of expected arguments to the number actually received. An error is thrown if they don't match:

[previous] [next]