Functions

Functions

Loops are great if you want to repeat somthing right now. What if you want to save a sequence of steps and execute them later whenever you want?

var sayHi = function() {
  log("Hello, everybody!");
};

// Run the function!
// We call this "invoking" the function.
sayHi();


// Do some other stuff
var x = "other stuff";

// Invoke it again!
sayHi();
sayHi();
sayHi();
sayHi();

Creating a Basic Function

var sayHi = function() {
  log("Hello, everybody!");
};
  • At first glance, creating a function looks a lot like creating a loop. Here's the general format:
    1. The function keyword
    2. Parenthesis (we'll talk about what goes inside of the parenthesis in a bit)
    3. A block of code
  • Note that unlike loops we actually assign the whole function to a variable. This gives us a name to use when we want to run the function later.
  • When you're ready to run the code inside of the function, "invoke" it by typing the name of the function followed by parenthesis, like this: sayHi();

You have already been using lots of built-in functions like parseInt, prompt, console.log, alert, etc..

Aside: Another Way of Writing Functions

There's another way of writing functions that you might see in your textbook. You can actually write the previous example like this:

function sayHi() {
  log("Hello, everybody!");
}

I don't care which way you do it, but to keep things simple I'm always going to write functions the other way.

Function Parameters

To make functions more useful, you can set them up to accept values to work with. We call these "parameters", but really they're just variables that automatically get filled with values you specify when you invoke the function.

var sayHiTo = function(name) {
  log("Hello, " + name + "!");
};

sayHiTo( "Brandon" );
sayHiTo( "Kaiti" );

You can also make functions that accept multiple parameters:

var sayHiToBoth = function(name1, name2) {
  var greeting = "Hello, " + name1;
  greeting = greeting + " and " + name2 + "!";
  log(greeting);
};

sayHiToBoth("Brandon", "Kaiti");
sayHiToBoth("Kaiti", "Brandon");

Function Arguments

When you invoke a function that has parameters, you should pass values for the function to work with when you invoke it. The technical term for these values are "arguments".

When you invoke a function, JavaScript takes whatever arguments you specify, sticks them in the function's parameters, and runs the function.

var sayHiToBoth = function(name1, name2) {
  var greeting = "Hello, " + name1;
  greeting = greeting + " and " + name2 + "!";
  log(greeting);
};

sayHiToBoth("Brandon", "Kaiti");

// What do you think will happen if 
// we leave out the second value?
sayHiToBoth("Brandon");

Scope

One more thing you need to know about functions.

Variables you define in functions only exist inside of the function.

This has a lot of implications, which we will hopefully have time to talk about later in this course.

More on Functions

Getting Values out of Functions

It seems like it would be very useful if we could get values back out of functions. That way if we had to do some sort of complicated calculations over and over again, we could just write a function to do it, give the function what it needs to calculate the value, and let the function give us back the result.

Surely there must be a way!

Return statement

The return keyword does two things:

  1. It immediately exits the function.
  2. It gives a value back to the code that called the function.

.

var oldEnoughToDrive = function(age) {
    if (age >= 16) {
      return true;
    } else {
      return false;
    }
};

var isOldEnough = oldEnoughToDrive( 16 );
log( isOldEnough );

We've already been using lots of functions that return values: Math.random(), Math.min(), and prompt() for example. This is how you can write your own.

Another Example

Let's create a diceRoll function that returns a random number between 1 and 6. This is almost identical to the one that I wrote for you to use in your dice game assignment.

var diceRoll = function() {
    var randomNumber = Math.random();       // randomNumber is between 0 and 1
    randomNumber = randomNumber * 6;        // randomNumber is between 0 and 6
    randomNumber = Math.ceil(randomNumber); // round up

    // Now randomNumber is between 1 and 6

    // Hand the result back to the code that calls the function.
    return randomNumber;
};

Another Example

Now let's use that function to simulate a simple game.

var roll1 = diceRoll();
log( "Bob rolled a: " + roll1 );

var roll2 = diceRoll();
log( "Timmy rolled a: " + roll2 );

if (roll1 > roll2) {
  log("Bob won!");
} else if (roll2 > roll1) {
  log("Timmy won!");
} else {
  log("It's a tie.");
}

Scope

Scope is whether or not a particular line of code can access a particular variable.

Global Scope

  • When a variable is declared outside of a function in the top level (more on this later) it is said to be a global variable
  • Variables that are not declared before they are assigned a value are automatically global variables.

.

iAmGlobal = 5;

.

log(iAmGlobal);

Block Scope

  • Some programming languages also have "block scope", meaning that any time you have a "block" of code (surrounded by {}), the variables you declare inside of that block can only be accessed inside of that block.
  • Javascript doesn't have this.

File Scope

  • In addition, some programming languages have a scope of variables for each file (if your program is split among multiple files).
  • Javascript doesn't have this either.

Function scope

  • Javascript has this!
  • Variables declared inside of a function can only be accessed inside of that function.

For example:

var hello = function() {
    var greeting = "hello";
    log(greeting);
};

hello();
log(typeof greeting);

Variable Shadowing

When a variable is declared in a child scope that is already available in a parent scope it is said to "shadow" or "mask" the other variable.

var greeting = 'goodbye';

var hello = function() {
  var greeting = 'hello';
  log(greeting);
};

hello();
log(greeting);

Lexical Scoping

  • JavaScript's approach to variable scope is called lexical scoping
  • Essentially this means that variables defined in a parent scope are available in the child scope too
  • THIS IS WHY THE VAR KEYWORD IS IMPORTANT

.

var greeting = 'goodbye';

var hello = function() {
  greeting = 'hello';
  log(greeting);
};

hello();

// The above function call modified the 
// global greeting variable!
log(greeting);

Advanced Topics: Creating Scope

One trick that advanced Javascript programmers often use is to create a new variable scope using an anonymous function that is executed immediately.

(function() {

  // Protect "myvalue" so no one else can edit it!
  var myvalue = 100;
  log(myvalue);

}());

The above is equivalent to:

var newscope = function() {

  // Protect "myvalue" so no one else can edit it!
  var myvalue = 100;
  log(myvalue);

};

newscope();

Scope: More Resources

For more scope examples in Javascript check out: this post on Stack Overflow.