Using Functions to Initialize and Make Decisions JavaScript

an article added by: Sonja Lande at 05312007


In: Root » » AJAX » Using Functions to Initialize and Make Decisions JavaScript

French Spanish Portuguese Italian German Japanese Chinese Korean Russian Arabic

Using Functions to Initialize and Make Decisions Problem You want to use functions to initialize and make decisions. Theory Usually when you write a piece of code where a change of logic needs to take place based on a context, you use a decision structure. For example, say you are implementing a light switch using a program. You turn on the light if the light is off, and you turn off the light if the light is on. The behavior of the program is determined by the conditions. One example behavior that deserves a closer look is initialization. Initialization typically should happen only if it hasn’t already. Initialization is important because the initialization logic creates the default framework for your application to properly function. Solution For illustrative purposes, let’s go through an example where a function requires an initialization that is embedded within the function. The logic is to perform an initialization if it has not already occurred. The function that is called is defined as follows, and it embeds a call to the initialization.

Tip You could use this type of code to implement a lazy initialization when writing convention-based code that does not perform an explicit initialization.

    Source: /website/ROOT/ajaxrecipes/javascript/makingdecisionsinitialization.html
    function ClassicalManipulateObject( obj) {
    info( "ClassicalManipulateObject",  "Starting");
    if(  !didInitialize) {
    DoInitialization(  obj);
    }
    else  {
    info(  "ClassicalManipulateObject", "no initialization  necessary");
    }
    assertEquals( 3, obj.value);
    info( "ClassicalManipulateObject",  "Ending");
 }

 

In the example, the bold code relates to the initialization functionality. didInitialize is a flag variable that can be either true or false. If the didInitialize variable is false, then initialization did not take place; if the didInitialize variable is true, then initialization did take place. If initialization did not take place, the DoInitialization function is called. Notice that in the logic is a variable that represents whether initialization has taken place and a function to do initialization. This code is problematic because the variable has to be defined somewhere, and the variable has to be assigned properly somewhere. And somewhere there is a cross-reference between the variable state and the calling of the initialization functionality. One solution is to embed much of the initialization logic in the context of the DoInitialization function. But the fact is that somewhere there is a variable, and somewhere there is an initialization function, and somewhere there is a cross-reference between the variable and initialization function. So where you put the logic is irrelevant in a “big picture” sense.

Another solution is to think of the initialization functionality not as a decision, but as a state. There is an initial state, which is to perform an initialization, and another state to perform no initialization. In a sense, the didInitialize variable is a representation of the state. Keeping that thought in mind, you know that JavaScript treats its functions as objects. Thus, the didInitialize variable could be a function and not a Boolean variable. Treating the state as a variable that references a function makes it possible to simplify the function that requires an initialization. The implementation of the ClassicalManipulateObject function is changed to ManipulateObject, as illustrated in the following code.

    Source: /website/ROOT/ajaxrecipes/javascript/makingdecisionsinitialization.html
    function ManipulateObject(obj) {
    info( "ManipulateObject",  "Starting");
    InitializeObject(  obj);
    assertEquals( 3, obj.value);
    info( "ManipulateObject",  "Ending");
 }

In the modified implementation, the bold code again represents the initialization functionality. Here there is no decision just a function call to InitializeObject. You might be thinking, “I could have done the same thing with the decision-based initialization, in that the decision is implemented in InitializeObject.” But this is incorrect, because in the implementation of InitializeObject, there is no decision. The implementation of InitializeObject initializes the variable and then allows the processing to continue. If there is no decision on whether the initialization occurred, and InitializeObject represents a function to initialize the state, then for every call the state will be initialized you can’t call this initialization functionality. The magic is in the fact that JavaScript treats functions as objects. The implementation of InitializeObject is as follows:

    function InitializeObject( obj) {
    obj.value = 3;
    info( "InitializeObject", "doing  initialization");
    InitializeObject  = InitializeEmptyObject;
 }

In the implementation of InitializeObject, the obj parameter is initialized to a value of 3, and the bold code shows the reassignment of the InitializeObject function. The reassigned InitializeObject references a function without body, which means that the first time InitializeObject is called, the initialization is carried out, but every call thereafter is an empty function call that does nothing.

This is the complete implementation of the initialization functionality without using a single decision or variable. One advantage of this approach is that you don’t need to figure out which variable to cross-reference with the function. The function takes care of itself, and the caller can keep calling InitializeObject, knowing that everything will be taken care of. Another advantage of this approach is that you are creating a state engine where the next state is determined by the execution of the current state. There is no centrally located decision block that determines the overall flow of execution and needs updating every time a new state needs to be integrated. Normally when writing code in a language such as Java, C#, or C++, you don’t go around reassigning the implementation of defined function. And because this behavior is engrained in the developers’ minds, they don’t even consider doing that. Yet there is absolutely no problem reassigning functions in JavaScript, because functions are objects. Functions are not unique identifiers with unique functionality, as you think of them when working with them in other languages.

The implementation of InitializeObject works and is a complete solution. But there is a little inconvenience in that once InitializeObject has been assigned to an empty function, the initialization functionality is lost until the HTML page is refreshed. For some problems, that is an acceptable solution. For example, you wrap XMLHttpRequest only once because you can instantiate XMLHttpRequest in only a certain browser-specific way. There are some instances, however, when you might want to reset and initialize again, and to be able to do that, you need to wrap InitializeObject into a function within a function, as demonstrated in the following example.

    Source: /website/ROOT/ajaxrecipes/javascript/makingdecisionsinitialization.html
    function ResetInitializeObject() {
    InitializeObject = function( obj) {
    obj.value = 3;
    info( "InitializeObject", "doing  initialization");
    InitializeObject = InitializeEmptyObject;
    }
    }
 ResetInitializeObject();

The InitializeObject function is a variable that is assigned a function implementation in the ResetInitializeObject context. Recipe 2-4 shows that there is no difference in how a function is declared, even if it seems odd or out of place. To initialize InitializeObject, the ResetInitializeObject function is called, thus creating the InitializeObject function. And InitializeObject when called will reassign itself to an empty function.

Calling ResetInitializeObject again resets the initialization, allowing InitializeObject to initialize the state and reset itself again. From this example, you can see that a decision does not need to be implemented using an if statement. Another example that illustrates how a state engine could be implemented follows. The example implements a light switch, where if the light is on, it is turned off, and vice versa. Note that not a single if statement is used in this example.

    Source: /website/ROOT/ajaxrecipes/javascript/makingdecisionsinitialization.html
    function ToggleLight() {
    ToggleLight.on = function() {
    ToggleLight.curr = ToggleLight.off;
    return "on";
    }
    ToggleLight.off = function() {
    ToggleLight.curr = ToggleLight.on;
    return "off";
    }
    try {
    return ToggleLight.curr();
    }
    catch( e) {
    info( "ToggleLight",  "initialization...");
    return ToggleLight.on();
    }
 }

The function ToggleLight is called whenever you want to switch the light on or off. There is no parameter to indicate an on or an off; that functionality is embedded within the ToogleLight function. In the ToggleLight implementation there are two properties, on and off, both of which are functions. The on function assigns the curr property to off and returns an "on" buffer. The off function assigns the curr property to off and returns an "off" buffer.

To toggle the state, the curr property that is defined as a function is called. The calling of curr is embedded in an exception block, because curr will not be initialized the first time ToggleLight is called. Thus, an exception is generated, and in the catch part of the exception block, the on property (which is a function) is called. Calling on automatically assigns curr and initializes the state. It is important to remember that using an exception block and calling on is acceptable because it is a way of implementing lazy initialization. When writing decision blocks and functions, think about state and the following aspects of this recipe:

• Your program does not need to include as many decisions, because decisions have been replaced by different states.

• You can reassign functions if you can break down the problem into a state engine problem.

• You can be more flexible with reassigned functions because behavior can be substituted dynamically. For example, if you require a two-stage initialization using a decision, that means additional if statements altered in a central location of source code. Using a reassigned function, you are creating a state engine where the behavior can be altered during runtime at the local level.

• When you read through this recipe’s examples, you may have thought, “Why not use a class and object?” The answer is that a function is an object and the examples are object-oriented programming. The code looks odd because we normally assume a function is a feature used to create a class, and that classes typically are not functions. If the notation bothers you, my advice is to let this feature of JavaScript stew in your mind for a bit. You will surely come to see it is a powerful way of programming.

Note For another example of using recursion instead of using decision blocks.

legal disclaimer

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.

related articles

1. Ajax
Given the recent interest in Ajax, you’d be forgiven for thinking it was a new technology. In fact, the XMLHttpRequest object has been around for years. In technical terms, asynchronous JavaScript interaction with the server is nothing new. All of the other elements of the Ajax model have also been around for quite some time: CSS, (X)HTML, and DOM Scripting. Yet in 2005, interest in this methodology soared. Could it really be that simply giving this approach a snappy name like Ajax was responsible for the sudde...

2. Understanding the Definition and Philosophy of Ajax
The focus of this article is to provide solutions to some common, general problems and questions that are bound to arise before or during development of Asynchronous JavaScript and XML (Ajax) and Representational State Transfer (REST) applications. These common questions are not always technical in nature, often leaning more toward theory or philosophy of development. The problem with these kinds of questions is that once you begin to think about them, you keep going in a circle and end up where you star...

3. 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...

4. 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:...

5. 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...

6. 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...

7. 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 ...

8. 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...