; PSY 1903
PSY 1903 Programming for Psychologists

Functions

When writing code, you will often find yourself needing to do the same thing repeatedly. As an example, in several of our examples/tasks, we’ve needed to generate a random number. The syntax to do that in JavaScript is a little verbose: Math.floor(Math.random() * 10) + 1;.

let num1 = Math.floor(Math.random() * 10) + 1;
let num2 = Math.floor(Math.random() * 10) + 1;

To streamline our code, we could define a function called getRandomNumber that returns a random number:

function getRandomNumber() {
    return Math.floor(Math.random() * 10) + 1;
}

Then, whenever we need a random number we could invoke that function and get our random number in a cleaner and more intuitive fashion:

let num1 = getRandomNumber();
let num2 = getRandomNumber();

Some key points to observe about functions so far:

  • A function is defined using the function keyword.
  • The function name we came up with in this example is getRandomNumber (see details below for guidelines on naming functions).
  • Following the name of a function, we define any parameters that function takes in parenthesis. If a function does not need parameters (as was the case in the above example), simply use empty parenthesis ().
  • The body of the function is defined within curly brackets {...}.
  • When a function produces some value it can be returned using the return keyword. The above function returned the random number that was generated, but not all functions will return a value.

Here’s an example of a function that has 2 parameters:

function calculateRectangleArea(length, width) {
    let area = length * width;
    return area;
}

// Example invoking the above function and writing it’s return value to the console
console.log(calculateRectangleArea(10, 10)) // 100

// Example invoking the above function and capturing its return value in a variable
let area = calculateRectangleArea(10, 5);
console.log(area) // 50

In the above example, the body of our function was very simple - calculate the area and return it. We defined area as its own variable for clarity, but we could refactor this code as follows:

function calculateRectangleArea(length, width) {
    return length * width;
}

Here’s an example of a function that does not return a value but instead has a side effect (updating the page):

function updateResults(content) {
    document.getElementById('results').innerHTML = content;
}

updateResults('Your answer was correct!');

Here’s an example of a function that returns a Boolean value:

function isSquare(length, width) {
    if (length == width) {
        return true;
    } else {
        return false;
    }
}

console.log(isSquare(10, 10)) // true
console.log(isSquare(15, 20)) // false

Observe how the above function could be simplified to:

function isSquare(length, width) {
    return length == width;
}

This simplification works because we know length == width is a Boolean expression that will evaluate to either true or false, so we can simply return that directly. This code is more concise, but if it’s helpful for you to see the full if/else written out, that’s okay!

Naming functions

Here are conventions/rules to follow when naming functions in JavaScript:

  • Descriptive: Function names should be descriptive and convey the purpose of the function. This helps make code more readable and maintainable.
  • Valid Characters: Function names can contain letters (both uppercase and lowercase), digits, underscores (_), and dollar signs ($). They can not start with a digit.
  • No Spaces: Function names cannot contain spaces. In this course we will use a lowerCamelCase convention in place of spaces when naming functions. lowerCamelCase style means that the first word is in lowercase, and every new word starts with a capital letter (ref).
  • Reserved Keywords: Function names cannot be the same as JavaScript keywords or reserved words. For example, you cannot name a function if, for, let, return, etc. Sometimes you might unknowingly use a reserved word, but if you do you’ll get an error so just be on the lookout for that.

When should you create functions?

Functions provide us a way to organize and streamline our code.

Typically, you’ll want to create a function if there are blocks of code you need to repeat within a program (or even amongst programs - there are ways to share functions across different files.).

Functions also help with abstraction. Abstraction allows us to neatly compartmentalize complex code, as was demonstrated with our getRandomNumber function. Abstraction can help simplify the “main flow” of a program, as we can focus on the big picture while calling upon functions to handle abstracted tasks.

Function order

Because JavaScript loads all functions into memory before they’re executed, you can invoke a function before it’s defined:

sayHi(); // This will work, even though sayHi is not defined until later in this file

function sayHi() {
    alert('hi!');
}

Local vs. global variables

Any variables defined outside a function are considered global variables and are available within functions. For example, the following code defines a global variable called greeting that is accessible within the function:

function sayHi() {
    alert(greeting);
}

let greeting = 'hi!';

sayHi();

Any variables which you define inside a function are only available to code inside the function. They are known as local variables. Example:

function sayHi() {
    let greeting = 'hi';
    alert(greeting);
}

console.log(greeting); // "ReferenceError: greeting is not defined"

The above code would produce an error because greeting was defined locally in the sayHi function and is therefor not available outside the context of that function.

Note that it’s better to pass any data you need to a function via parameters instead of relying on global variables as it helps to make the function more independent from the rest of the code. Functions that are designed to operate independently from the rest of the code are ideal as they are more modular (i.e. easier to use across different files/programs) and easier to test/debug.

Third-party functions

In addition to creating your own functions, you can import functionality that other programmers have created. Using third-party code libraries is a common practice in programming because it saves time by preventing us from having to “re-invent the wheel”. As an example of this, we will be using the JavaScript library jsPsych to take advantage of a bunch of pre-built experiment-related utilities.