2

I am a beginning JS programmer working through codeschool's 3rd JS course. One of their modules introduces the concept of passing function expression variables as parameters for other functions. However, I need some help understanding why this method is better in some cases than in others. For example, the following code is for a conditional alert that is supposed to recognize whether the user is a new user and throw a customized greeting when the user logs out of the system.

This is what codeschool advocates:



    var greeting;
    var newCustomer;

    //Some code sets the variable newCustomer to true or false

    if( newCustomer ){
        greeting = function () {
            alert("Thanks for visiting the Badlands!\n" + 
            "We hope your stay is...better than most.");
        
        };
    } else {
        greeting = function () {
            alert("Welcome back to the Badlands!\n" + 
            "Guess they aren't so bad huh?");
        };
    }

    closeTerminal( greeting );

    function closeTerminal( message ){ message();}


But why is that better than the following?



    var greeting;
    var newCustomer;

    //Some code sets the variable newCustomer to true or false

    closeTerminal();

    function closeTerminal(){ 

        if( newCustomer ) {
            alert("Thanks for visiting the Badlands!\n" + 
            "We hope your stay is...better than most.");
    
        } else {
            alert("Welcome back to the Badlands!\n" + 
            "Guess they aren't so bad huh?");
        }
    } 


Which of these code blocks (or any other code) would a good developer use to achieve the desired result? Is there an advantage to storing an entire function in a variable over just using a single if . . . else statement to evaluate newCustomer and return the desired greeting?

jdw
  • 3,755
  • 3
  • 17
  • 16
  • 2
    The first one keeps `newCustomer` local to the function that calls `closeTerminal()`; the second approach requires a "global" variable. – Ja͢ck Jun 20 '14 at 03:46

4 Answers4

3

In your case, it is not inherently better.

But there are cases where it isn't this simple. Assume that you cannot modify the closeTerminal function, but its developer still wants you to execute arbitrary functionality from deep with his logic? That's where you use a callback function. Passing function expressions for them is only natural, but not strictly required. Have a look at purpose of callbacks in javascript maybe.

Another usecase for callbacks are asynchronous functions, you might encounter them later.

A better example might be

function closeTerminal(getMessage) {
    var isNewCustomer = !Math.round(Math.random()); // complicated, local logic

    var message = getMessage(isNewCustomer);
    alert(message); // print to the closing terminal
    // (which is local to this function as well)
}

You could invoke it with

closeTerminal(function greeting(newCustomer) {
    // passing a custom function to determine the appropriate message
    if (newCustomer)
        return "Thanks for visiting the Badlands!\nWe hope your stay is...better than most.";     
    else 
        return "Welcome back to the Badlands!\nGuess they aren't so bad huh?";
});
Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
0

Here's an example of their use:

function load_home() {
    var url = "http://localhost/inner_load/page_test.html";
    var method = "GET";
    var postData = " ";
    var async = true;
    var request = new XMLHttpRequest();

    /* Have a close look at this */
    request.onload = function () {
        var data = request.responseText;
        Contenido.innerHTML=request.responseText;
    }

    request.open(method, url, async);
    request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
    request.send(postData);
}

As you can see, I can specify a function that defines an action that will be performed when the server returns a result. Another example would be:

function add(a, b) {
    return a+b;
}

function mult(a, b) {
    return a*b;
}

function calculate(func, a, b) {
    return func(a, b);
}

In this case I can choose what to do with the values passed as a and b by passing a function as a parameter, if I pass add, the two numbers will be added, if I pass mult, they'd be multiplied.

calculate(add, 10, 5);

Will return 15. Where:

calculate(mult, 10, 5);

Would return 50.

This would save you a lot of trouble if you are doing, say, a calculator. Instead of using an if … else block and some var storing some integer numbers or strings to define the operations you want to perform, you could just call the function giving the operation you'd want to perform.

arielnmz
  • 8,354
  • 9
  • 38
  • 66
0

The concept of scalability and reusability. With your code it definitely works. For now. Any change requested from client would require you to modify a hell lot of code. While maintaining such granularity with functions, allows you to write code that works and works well.

I myself haven't gone through any codeschool tutorials but you might find Functions chapter in eloquent javascript interesting. Here is a link you can use.

0

In your version of the solution, you will always greet the user with only alert box. The version in the tutorial gives the caller of closeTerminal method the flexibilty to pass any method which can contain any logic. i.e show message in alert or in a new jquery ui dialog or bootstrap dialog or a completely different logic.

Please see the following code to understand how we can reuse your logic.

HTML

<div id="myDiv"></div>

Javascript

var greeting;
var newCustomer;

//Some code sets the variable newCustomer to true or false

if( newCustomer ){
greeting = function () {
         alert("Thanks for visiting the Badlands!\n" + 
        "We hope your stay is...better than most.");  
 };
}else {
    greeting = function () {
        alert("Welcome back to the Badlands!\n" + 
        "Guess they aren't so bad huh?");
    };
}
function closeTerminal( message ){ message();}

function divGreeting(){
    document.getElementById('myDiv').innerHTML = "Thanks for visiting the Badlands!\n" + 
            "We hope your stay is...better than most."
}

closeTerminal( greeting );
closeTerminal( divGreeting );

Working sample - http://jsfiddle.net/7P2Ct/

Sherin Mathew
  • 1,141
  • 13
  • 19