JavaScripot Functions

an article added by: Sonja Lande at 05312007


In: Categories » Computers and technology » AJAX » JavaScripot Functions

Treating Functions Like Objects

Problem You want to take advantage of the fact that functions are objects (remember, everything is an object in JavaScript). Theory Many people think that a function is some keyword used in JavaScript. A function is also an object that can be manipulated. Knowing that a function is an object makes it very interesting from the perspective of writing JavaScript code, because the code can treat the function like another other object. This means you could assign functions to variables, class properties, and what have you. Solution One way of using this capability is to implement the Factory pattern to return a function object. For example, in Ajax you have two ways to instantiate the XMLHttpRequest object, and the method used depends on the browser.

The Factory pattern is used to separate the interface from the implementation. Usually that means implementing an interface, but because JavaScript is a dynamic language, there is no real notion of an interface. In a dynamic language, an interface is not necessary because you can call a method directly without requiring a specific type. In the case of the XMLHttpRequest object instantiation, the Factory pattern returns a function reference that can be used to instantiate XMLHttpRequest using the appropriate technique. In JavaScript, a function is an object that can be assigned to a variable. A way of implementing the factory that instantiates XMLHttpRequest is to use function assignments. The complete implementation is as follows.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function InstantiateIEXMLHttpRequest() {
    return new ActiveXObject(  "Microsoft.XMLHTTP");
    }
    function InstantiateOthersXMLHttpRequest() {
    return new XMLHttpRequest();
    }
    function FactoryXMLHttpRequest() {
    if( window.XMLHttpRequest) {
    return InstantiateOthersXMLHttpRequest;
    }
    else if( window.ActiveXObject) {
    return InstantiateIEXMLHttpRequest;
    }
    throw new Error( "Could not instantiate  XMLHttpRequest");
 }

In the preceding example, the FactoryXMLHttpRequest function is the implementation of the Factory pattern. Within the function implementation are two if statements that verify which browser is currently running. Depending on the browser, the return statement will return a reference to either the InstantiateIEXMLHttpRequest function or the InstantiateOthersXMLHttpRequest function. In both cases, the returned reference is a function that will instantiate the XMLHttpRequest object. The code that uses the FactoryXMLHttpRequest method follows.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    factory_function : function() {
    var InstantiateXMLHttpRequest =  FactoryXMLHttpRequest();
    var xmlhttp = InstantiateXMLHttpRequest();
    assertNotNull( xmlhttp);
 },

Notice in the example how the InstantiateXMLHttpRequest variable can be treated as a function. For illustrative purposes, the InstantiateXMLHttpRequest variable uses a mix of uppercase and lowercase letters to illustrate that when the variable is called, it looks like a function call. Based on the identifier and the context in which the variable is used as a function, you would not know that the variable is not a function.

This is a very important point, because it illustrates that a function is just another object. FactoryXMLHttpRequest is coded using a traditional approach: the code declares a function that when called will return an instance of a function. The behavior of the code is determined after the code has been parsed and initialized. With JavaScript, this is not necessary, because you can initialize the functions when the code is being parsed to optimize it. For example, you could rewrite the FactoryXMLHttpRequest code as follows.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
 <script language="javascript">
 if( window.ActiveXObject) {
 InstantiateXMLHttpRequest = function() {
 return new ActiveXObject( "Microsoft.XMLHTTP");
 }
 }
 else if( window.XMLHttpRequest) {
 InstantiateXMLHttpRequest = function() {
 return new XMLHttpRequest();
 }
 }
 else {
 throw new Error( "Could not instantiate  XMLHttpRequest");
 }
 </script>

In the modified implementation, the code used to assign the InstantiateXMLHttpRequest variable is executed as the HTML page is loaded. Thus, whenever the InstantiateXMLHttpRequest variable is referenced as a function, the appropriate way of instantiating XMLHttpRequest is executed. There is no need to call a factory and make a decision each and every time the function is called. This ability to treat functions as objects adds an interesting coding facet, in that the behavior of the code can be determined at runtime. Where normally you would use a decision structure to determine the appropriate behavior, a dynamically assigned variable can be used. Because a function is an object, there are some additional coding possibilities. For example, it is possible to dynamically assign properties and methods to a function, as shown in the following example.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function FunctionFunctionProperties(cmpval) {
    assertEquals(cmpval,  FunctionFunctionProperties.value);
    }
    var VariableFunctionProperties = function(  cmpval) {
    assertEquals( cmpval,  VariableFunctionProperties.value);
    }
    var startIndex =  VariableFunctionProperties.toString().indexOf( "{");
    var endIndex =  VariableFunctionProperties.toString().lastIndexOf( "}");
    var buffer = VariableFunctionProperties.toString().slice(  startIndex + 1, endIndex);
 var InstantiatedFunctionProperties = new  Function( "cmpval", buffer);

This example shows three function declarations, with each declaration illustrating a different way to declare a function instance. The first declaration, FunctionFunctionProperties, is the traditional approach. The second declaration, VariableFunctionProperties, uses a variable and an anonymous function. And the third declaration, InstantiatedFunctionProperties, is an explicit instantiation of the Function object, where the constructor parameters represent the declaration of the parameters, and the last parameter is the function body.

The function body is a buffer of JavaScript code that is converted into executable JavaScript. For each of the three function implementations, the name of the function is referenced and appended with a reference to the property value. With each and every function instance you can assign a property or, if you so desire, another function reference. You can think of properties as a way to declare a static variable that is associated with the function. Because each of the three function declarations represents an object and a variable, they can be called in an identical fashion, as illustrated in the following example.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function_with_properties : function() {
    VariableFunctionProperties.value = 10;
    VariableFunctionProperties( 10);
    FunctionFunctionProperties.value = 10;
    FunctionFunctionProperties(10);
    InstantiatedFunctionProperties.value = 10;
    InstantiatedFunctionProperties( 10);
    testManager.success();
 },

Reading the code that calls the declared functions takes a bit of getting used to. Before each function call, the identifier is used as if it were an object. After the object is referenced, the object is called as a function. These examples clearly indicate that functions have a dual nature, where functions are objects and objects can be functions. This dual nature poses a problem: how does the function implementation know the instance of the function? The following code illustrates this problem.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function_with_properties : function() {
    VariableFunctionProperties.value = 10;
    VariableFunctionProperties( 10);
    FunctionFunctionProperties.value = 10;
    FunctionFunctionProperties(10);
    InstantiatedFunctionProperties.value = 10;
    InstantiatedFunctionProperties( 10);
    testManager.success();
 },

Reading the code that calls the declared functions takes a bit of getting used to. Before each function call, the identifier is used as if it were an object. After the object is referenced, the object is called as a function. These examples clearly indicate that functions have a dual nature, where functions are objects and objects can be functions. This dual nature poses a problem: how does the function implementation know the instance of the function? The following code illustrates this problem.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function GetFunction() {
    return function( cmpvalue) {
    assertEquals(cmpval, unknownfunctioninstance.value);
    }
 }

In the example, the GetFunction function has an implementation that returns a unique function instance each and every time GetFunction is called. If you wanted to reference a property of the function instance, you would be hard pressed to do so, because an anonymous function has no associated identifier. In the previous examples, the reference to the function instance was used to reference the properties and methods of the function object. Using this way of declaring the function, there is no associated instance identifier, and no way to be able to reference the property of the anonymous function. The solution is to use an internal variable that is referenced, as the following example demonstrates.

    Source: /website/ROOT/ajaxrecipes/javascript/functionsareobjects.html
    function GetFunctionFixed() {
    var inst = function(cmpval) {
    assertEquals(cmpval, inst.value);
    }
    return inst;
 }

How the code that fixes the problem of the unknown instance actually even works may seem a bit mysterious at first. It involves the use of a programming technique commonly known as a closure. To understand how closures work, remember to think of a function as an object, not some function keyword construct. Here’s what happens in a nutshell:

1. The caller calls GetFunctionFixed.

2. The implementation of GetFunctionFixed is executed.

3. An anonymous function is declared, and a Function object is instantiated.

4. The instantiated anonymous function is assigned to the local declared variable inst.

5. The anonymous function references inst, and the JavaScript processor understands this and creates a reference to the local declared variable.

6. The inst variable is returned to caller.

7. The garbage collector attempts to garbage collect inst, but it cannot because the anonymous function references inst as long as anonymous is referenced somewhere. When you consider the steps in this process together with the fact that everything is an object, it becomes easy to see how this code works. When an object references another object, the objects can only be garbage collected if they do not reference anything. When using functions and treating them as objects, keep the following points in mind:

• Functions are objects, and you can manipulate them like any other JavaScript objects. However, because functions are objects, using functions improperly or properties of functions improperly can cause memory leaks, where memory is referenced and not garbage collected, even though the script is not making use of the memory.

• A configuration of functions or methods is possible when the HTML page is being loaded. This saves processing logic, as the code does not need to determine what code should be executed.

• It takes a bit of time and experimentation to get used to the idea that the behavior of code is determined at runtime, and not while you’re writing the code.

• Being objects, functions can reference properties or methods, enabling functions to define behavior at runtime. If you do assign properties or methods to functions, then do so with the understanding that the properties and methods are transient that is, if a function is copied from one instance to another, do not assume that the properties are copied too.

legal notice

Our website is not responsible for the information contained by this article. Web-articles is a free articles resource.
Suggestion: If you need fresh, daily updated content for your website, feel free to use our service. Click here for more information.

Useful tools and features

Link to this article from your page    Send this article to you or to a friend
If you like this article (tutorial), please link to it from your web page using the information above.

related articles

1. Understanding the Definition and Philosophy of Web Services and SOA
Understanding the Definition and Philosophy of Web Services and SOA Wikipedia offers the following definition of Web services:4 The W3C defines aWeb service as a software system designed to support interoperable machine-to-machine interaction over a network. This definition encompasses many different systems, but in common usage the term refers to those services that use SOAPformatted XML envelopes and have their interfaces described by WSDL. For ex...

2. Understanding the Definition and Philosophy of REST
Understanding the Definition and Philosophy of REST REST is a controversial topic among Web service enthusiasts, because it’s considered to stand for the opposite of what Web services and SOA are trying to achieve. The problem with this thinking is that REST is not in contradiction with the abstract definition of SOA and Web services. REST is in contradiction with technologies such as SOAP, WSDL, and WS-* specifications. The following offers a quick definition of REST:...

3. The Easiest Way to Get Started with Ajax and REST
The Easiest Way to Get Started with Ajax and REST Problem You want to know the best way to get started with writing Ajax and REST. Solution When developing an Ajax and REST application, you must decide on the tools and frameworks you’ll use. The choice is simple: Use whatever you’re using today, and write some Ajax applications. You don’t need to change the tools you’re using today. Whether you’re using ASP.NET, JavaServer Pages (JSP), PHP, Ruby, or Python, you...

4. Testing a Dynamic Contract with Ajax
Coding the Contract Using Test-Driven Development Techniques Coding the contract using agile and test-driven development techniques requires writing a number of tests and implementing aMock URL layer. Problem You want to code the contract using these development techniques. Solution To demonstrate, let’s define a use case, implement the use case as a contract, write a test case(s) to implement the contract, implement the contract in the Mock URL, and finally...

5. Testing the Client Side Logic
Problem You want to effectively test your application’s client-side logic. Theory Testing GUI code tends not to be a productive task because of the complications that arise. The main complication is how to test the correctness of a user interface. Imagine a situation where clicking a button causes a table to be filled with data. Now imagine that when a check box is checked and the button is clicked again, a different table is filled with content. The fact that clicking the same button results in two ...

6. Understanding JavaScript and Types
Understanding JavaScript and Types Problem You want to work around the fact that JavaScript does not have types declared for its variables. Theory JavaScript code does not have any variables with a declared type. The lack of typed variables is apparent when you declare functions. That said, not having typed variable declarations does not mean JavaScript has no types or no type safety. Let’s start out with the simple declaration of a function, as illustrated by the following ex...

7. Coding Using Conventions and Not Configurations
Coding Using Conventions and Not Configurations Problem You want to make your JavaScript constructs more efficient by applying the Rails “convention over configuration” principle to them. Theory You may already be familiar with the programming platform Ruby on Rails, which is used to build Web applications. The focus of this recipe is not Ruby on Rails, but one aspect of Ruby on Rails namely, convention over configuration (see http://en.wikipedia.org/wiki/ Ruby_on_Rails for m...

8. Advantage of parameterless functions in JavaScript
Using Parameterless Functions Problem You want to take advantage of parameterless functions in JavaScript. Theory JavaScript functions for the most part have parameters. You may think that the previous sentence states the obvious after all, without parameters, what data could be passed to a function? JavaScript has the ability to declare functions that have no parameters, even though the caller of the function has passed parameters to the function. For example, let’s look at...

9. Implementing an Error and Exception Handling Strategy
Implementing an Error and Exception Handling Strategy Problem You want to implement a clean error and exception handling strategy in your applications, to make them run more smoothly. Theory Of course, you might argue that one error is a dialog box and the other is generated in the JavaScript console. The fact that one browser uses a dialog box to show an error and the other does not is a browser issue, not an error issue. A concise way of classifying the two errors is to ...