Functions: declarations and expressions

  1. The syntax
    1. Returning a value
    2. Local variables
  2. Function Declaration
  3. Function Expression
    1. Use declarations, please
  4. Function is a value
    1. Passing a function around
  5. Running at place
  6. Named function expressions
  7. Function naming
  8. Summary

A function, like a variable, can be defined anywhere in the code.

JavaScript provides several ways of defining them:

  • Function Declaration
  • Function Expression
  • Function as a result of a new Function call

The syntax

The basic syntax to create a function is a Function Declaration. The syntax is:

function f(arg1, arg2, ...) {
   ... code ... 
}

Looks like this:

*!*
function sayHi(name) {
  alert("Hi, "+name)
}
*/!*

sayHi('John')

The example above declares a function named sayHi with a single argument name and calls it.

Returning a value

To return a value, use return statement:

function sum(a, b) {
  *!*return a+b*/!*
}

var result = sum(2,5)
alert(result)

If a function does not return anything, it’s result is considered to be a special value, undefined. You can check it out on the following example.

function getNothing() {
  // no return 
}

var result = getNothing()

alert(result)

An empty return gives same result:

function getNothing() {
  return 
}
alert( getNothing() === undefined ) // true

Local variables

A function may contain variables, defined by var. Such variables are called local and are only visible inside the function.

function sum(a, b) {
  var sum = a + b

  return sum
}

Create a function min(a,b) which takes two numbers and returns the lesser one.

min(2, 5)  == 2
min(3, -1) == -1

Open solution
Solution

The code with if:

function min(a, b) {
  if (a < b) {
    return a
  } else {
    return b
  }
}

The solution with ternary operator:

function min(a, b) {
  return a < b ? a : b  // a if condition (a<b) is true, b otherwise
}


Write a function pow(x,n) which returns x in the n-th power. Or, in other words, x is multiplied by itself n times.

pow(3, 2) = 3*3 = 9
pow(3, 3) = 3*3*3 = 27
pow(1, 100) = 1*1*...*1 = 1

Create a page with prompts for x and n, then outputs the result of pow(x,n).

The demo: tutorial/intro/pow.html

Open solution
Solution

The solution: tutorial/intro/pow.html

Function Declaration

Nested functions come later

Here in this section, we are not talking about advanced topics like nested functions. They are covered later in Initialization of functions and variables and the next articles.

Everything in due time, right now we need to get the most important stuff right.

Function Declarations are parsed at pre-execution stage, when the browser prepares to execute the code.

That’s why the function declared this way can be called both after and before the definition.

This works:

function sayHi(name) {
  alert("Hi, "+name)
}

sayHi("John")

… But changed order also works:

sayHi("John")

function sayHi(name) {
  alert("Hi, "+name)
}

A function can be declared anywhere in the code.

For example, we may want to declare a function differently, depending on the condition:

sayHi()

if (1) {
  function sayHi() {  alert(1)  }
} else {
  function sayHi() {  alert(2)  } // <--
}

Try running the example above in different browsers. At the time of writing, Firefox gives error, other browsers output 2.

That’s because the declarations are parsed before the execution. According to the specification (p.10.5), the latter function with same name overwrites the existing one.

When it comes to execution, the declarations are ignored. So the if statement doesn’t affect anything.

Function Expression

A function in JavaScript is a first-class value, just like a number or string.

Anywhere where you could put a value, you can also put a function, declared “at place” with a function expression syntax: function(arguments) { ... }.

For example, you can do:

var f = 5

But you can also assign it to a function expression:

var f = function(name) {
    alert("Hi, " + name + "!");
}

When `function` means Expression and when it's a Declaration?

The rule is simple.

When the JavaScript parser sees a function in the main code flow, it assumes Function Declaration.

When a function comes as a part of a statement, it is a Function Expression.

Function Expressions are created when the execution flow reaches them. As a consequence, Function Expressions can be used only after they are executed.

var sayHi

// sayHi() <-- can't call here, there is no sayHi yet

if (1) {
  sayHi = function() {  alert(1)  }
} else {
  sayHi = function() {  alert(2)  }
}

sayHi()

In the example above, the result is the same in all browsers.

Use declarations, please

In the code of unexperienced developers, functions are often declared by expressions:

... code ...
var f = function() { ... }
...

Function Declarations are much more readable and shorter. Use them instead.

... code ...
function f() { ... }
...

Besides, functions declared this way can be called before it’s definition.

Use expressions only if you mean it. E.g for conditional function definition.

Function is a value

A function in JavaScript is a regular value. We could even output it:

function f() { alert(1) }

alert(f)

The example above outputs the function. Usually as the source code.

Both declarations and expression declare a variable and put the function into it. Only the creation time is different.

Passing a function around

Just like any value, a function can be assigned, passed as a parameter for another function and so on.

And it doesn’t matter how it was defined, for example:

function sayHi(name) {
  alert("Hi, "+name)
}

var hi = sayHi // assign a function to another variable

hi("dude")     // call the function

The function is assigned by reference. That is, a function is kept somewhere in memory and sayHi is a reference (or you could say pointer) to it. When I assign it to hi, both variables start to reference the same function.

One function can accept another function as an argument.

function runWithOne(f) {  // runs given function with argument 1
  f(1)
}

runWithOne( 
  function(a){ alert(a) } 
)

Logically, a function is an action. So, passing a function around is transferring an action which can be initiated from another part of the program. This feature is widely used in JavaScript.

In the example above, we create a function without a name, and don’t assign it to any variable. Such functions are called anonymous functions.

Running at place

It is possible to create and run a function created with Function Expression at once, like this:

(function() {

  var a, b    // local variables 
 
  // ...      // and the code 

})()

Running in place is mostly used when we want to do the job involving local variables. We don’t want our local variables to become global, so wrap the code into a function.

After the execution, the global namespace is still clean. That’s a good practice.

Why function is in brackets? That’s because JavaScript only allows Function Expressions to be called in-place.

Function Declarations can’t be called like that:

function work() {
  // ...
}()  // syntax error

Even if we remove the name, JavaScript would see the function keyword and try to parse Function Delaration:

function() { // error, function declaration without name.
  // ...
}()

So, the only way is to wrap the function in brackets. Then the interpreter consider it as a part of a statement, hence a Function Expression.

If the function is obviously an expression, then there’s no need in wrapping it, for instance:

var result = function(a,b) { return a+b }(2,2)
alert(result) // 4

In the code above, the function is created and called instantly.
That’s just like var result = sum(2,2), where sum is replaced by a function expression.

What will be the result of code execution? Why?

var a = 5

(function() {
  alert(a)
})()

P.S. Think well! Pitfall ahead! Ok, you’ve been warned Smile

Open solution
Solution

The result is error. Try it:

var a = 5

(function() {
  alert(a)
})()

That’s because no semicolon after var a = 5. JavaScript treats the code as:

var a = 5(function() {
  alert(a)
})()

So, it tries to call 5 as if it were a function, which leads to an error. The working code:

var a = 5;

(function() {
  alert(a)
})()

This is probably the most dangerous pitfall of optional semicolons in JavaScript.

There is one more way which uses a direct call to Function constructor. It takes arguments list and body as strings and creates a function from them:

var sayHi = new Function('name', ' alert("Hi, "+name) ');

sayHi("Benedict");

It is used very very rarely, almost never.

Named function expressions

A function expression may have a name:

var f = function sayHi(name) {
  alert("Hi, "+name)
}

The syntax is called named function expression (or NFE) and works as it should in all browsers except IE<9.

In those browsers which support it, the name is visible inside the function only:

var f = function sayHi(name) {
  alert(sayHi) // outputs function
}

alert(sayHi) // error: undefined variable 'sayHi'

IE will actually create two function objects in such case: sayHi and f:

var f = function g() {  }

// false in IE, error (g is undefined) in other browsers
alert(f=== g)

NFEs exist to allow recursive calls from anonymous functions.

See the following factorial function wrapped into setTimeout call:

setTimeout(function factorial(n) { 
  return n == 1 ? n : n*factorial(n-1) 
}, 100)

What is the result of the code? Why?

( function g() { return 1 } )

alert(g)

Open solution
Solution

The answer is error:

( function g() { return 1 } )

alert(g)

The key to the solution is understanding that (function ... ) is a function expression (see Functions: declarations and expressions), not a function definition.

So, we have a named function expression.

The name of a named function expression is visible only inside it.

All browsers except IE<9 support NFEs, so they will give ‘undefined variable’ error, because name g is only visible inside the function.

IE<9 doesn’t support NFE, so it will output the function.

Function naming

A function is an action. So it’s name should be a verb, like get, read, calculateSum, etc.

Short function names can be allowed if:

  • A function is temporary and used only in nearest code. Same logic as with variables.
  • A function is used everywhere in the code. So from the one hand, there is no danger to forget what it does, and from the other hand, you have less writing.

    The real-world examples are ‘$’, ‘$$’, ‘$A’, ‘$F’ etc. JavaScript libraries use these names to make frequent calls shorter.

In other cases, the name of a function should be a verb or multiple words starting with a verb.

Summary

Functions in JavaScript are regular values. They can be assigned, passed around and called when needed.

  • A function which returns nothing actually returns special value: undefined.
  • Use verbs to name functions. Short names are allowable in two edge cases: a name is used in the nearest code only, or it is extremely widely used.
Function Declaration Function Expression
function is used in the main code flow function is created as a part of an expression.
Created at pre-execution stage. Can be called both before and after the definition. Created when the execution reaches it. Can be called only after creation.
  Can be called in-place

Generally, it is recommended to use Declaration unless there is a reason for Expression.

Tutorial

Donate

Donate to this project