Functions in JavaScript

Functions in Javascript

We're about to deep dive into Functions in JavaScript and, as you'll see, this is where you start to see some major differences from Java. I know because they have a similar name and syntax, it's easy to assume that the two languages are the same, but JavaScript is a lot less rigid in its form, which is very apparent in how Functions are constructed. Let's get into it!

Function Declarations 

Functions are what we would think of as methods in Java, a block of code that performs a task when called upon. We previously discussed how JavaScript doesn't require data types in variable declarations, and the same thing applies to functions. You don't have to specify the return type in the function's signature, nor do the parameters reference a data type.

Function Declaration Syntax

Declaring a function requires the "function" keyword, a name, the parameter(s), the keyword "return" and a return statement.
function name (parameter) {
     return statement;
}

Basic Function Example

In this example, I wrote a basic function to calculate area.

As you can see, the parameters pass in the arguments height1 and width1, but do not alter them when the function is called. However, that is not the case when you pass in an object, like an array or user-defined object, as you'll see below.

Object Function Example

Here I've created a function (myFunc) that takes in an object (theObject) and changes its eyeColor property to "brown." I've also created a myPerson object with the properties of name and eyeColor. When I call myFunc on the myPerson object, it permanently changes that property's value.

Function Expression Declaration Syntax

Functions can also be written as expressions assigned to a variable. In this case the function can be anonymous, without a name. Though you can name the function, giving the ability to call it within itself or to help with debugging.
var name = function (parameter) {return statement; };

Anonymous Example 

Here, I created the same area function, but as an expression held in a variable.

Named Example

In this example, giving the function the named "fac", allows me to call it inside the function to calculate the factorial of a number.

You'll notice that this function also uses the ternary conditional expression we learned about in an earlier post to return 1 if the argument is less than 2, or calculate the factorial calling the "fac" function.

Note: This function can refer to itself in one of three ways:

  • fac(n) - the function itself
  • factorial(n) - the in-scope variable that refers to it - factorial(n)
  • arguments.callee() - callee property of the arguments object calls the currently executing function inside the function body of that function. 

Scope & Hoisting

Scope is a key factor in which variables, functions and objects can be accessed by function. At the top global level, a function can access global variables or objects created at that level. When called inside a variable or another function, it can only access the items in the parent.
Variables defined inside a function cannot be accessed from anywhere outside the function, because the variable is defined only in the scope of the function. However, a function can access all variables and functions defined inside the scope in which it is defined. In other words, a function defined in the global scope can access all variables defined in the global scope. A function defined inside another function can also access all variables defined in its parent function and any other variable to which the parent function has access. (Mozilla JavaScript MDN)
As we discussed with Variables, a function declaration can be hoisted, meaning that even though it appears below the call to it in the code, the declaration will be hoisted (or raised) to allow for execution.

The exception here is with Function Expressions. As we saw with variables, when a variable is hoisted, the value assigned to it, here the area1 function, is not brought with it. It is declared as "undefined" and therefore, not an executable function.

Scope & Hoisting Example

This example shows two versions of the area function, one as a named function (area), the other as a function expression (var area1). Only the named function is hoisted properly.


Nested Functions and Closures

Functions can be nested inside each other, either by calling on itself (a recursive behaving requiring a conditional, or break to prevent infinite loops) or by creating functions inside another function.

In either case, the scope of the inner function includes:

  • Its own variables & parameters.
  • The variable and argument values of the parent function.
  • Global variables, if the parent function is on the global level.
Conversely, the parent function cannot access the variables or parameters of the inner function.

Nested Function Example 

In this example there are two nested functions that each take an input parameter. The inner function adds both parameters and returns them. The outside function returns the inside function.

So, the input value of 3 is assigned to x and on the return, the inside function takes control. It still has access to the x value, but when you assign outside to a variable (outside1), that variable becomes a function that adds any input value to x or 3. When outside1(5) is called, it adds that value to the previously stored 3, returning a value of 8 from the inside function.


You can also call a nested function with both function's arguments, like in the last line of code.

Note: Be careful in how you name your parameters/variables in nested functions. Naming conflicts can occur if the inner function parameters have the same name as an outer function variable or parameter. The inner function takes precedence. The scope chain being; inner, outer, global.

Nested functions is how the concept of Closures come in to play. I'm not gonna lie, closures are somewhat confusing to understand, but hopefully my example will make it easier.

Closure - is a function having access to the parent scope, even after the parent function has closed. (W3Schools)

Closures can be used to make variables private. For example, if you had a global variable for a counter, any function in the global scope can access and modify it. However, if you make a counter a local variable in a function, it gets reset to to the initial value every time the method is called.

Closure Example

Using the counter issue I mentioned above I created a function (counterFunc) that declares a counter variable and has a nested anonymous function to increase the counter's value. By returning that nested function, the counter variable will only be initialized when it is assigned to the add variable. On any subsequent calls to add(), the counter value exists in the nested function.


The first line in the console shows the code being executed when the add() function is called.

Unique Features of JavaScript Functions

Default Parameters

In the function declaration you can specify a default parameter value, which is handy if you forget to code it in.

Default Parameter Syntax

function name (parameter = value) {
     return statement;
}

Default Parameter Example

Back to our good old friend, the area function. I defined a default width of 10, which was used in the first function call, but overridden in the second.

Arrow Expression Functions

The arrow expression is a way to shorten syntax in functions and I haven't come across this syntax in other languages, so I thought it was worth sharing.

Essentially, the arrow, sometimes called the "fat arrow" allows you to shorten a function down to one simplified line of code.

Arrow Expression Syntax

var name = () => { statements } //no parameters + statements
var name = (parameters) => { statements } //parameters and statements
var name = parameter => expression //one parameter, returning an expression

Arrow Expression Example

In the first example, I reduced the area function down to a single line using an arrow expression. 

In the second example, I called the map method, used to apply a function to every element in an array, on the 'a' array to count the length (s.length) of the Strings (s) in the array. Using the arrow expression, I was able to reduce the code to the bare minimum.  


As always, for more in depth explanations of JavaScript Functions visit the official Mozilla JavaScript MDN

Comments