Created by Tomasz Primke / tprimke (at) gmail (dot) com
The last update: 3rd March 2015
And then, the second part...
What is a function?
A function is a block of code, with optional arguments, that can be called.
Functions are used for:
What's the difference between function expressions and function statements?
The function defined by expression, cannot be called before it was defined.
The function defined by statement, can be called.
You probably know, what variables are.
But what are scopes?
Scopes are blocks of code, where variables are available.
prod variables are local.
factorial variable is global.
factorial variable is bound to a function.)
All the local variables are declared at the beginning of their function.
It means, that this code:
is equivalent to this code:
A good practice is to declare all the local variables at the beginning of a function.
In this example, both variables
prod are global.
The reason is simple: they are introduced in the
factorial function without the
Any variable introduced without the
var statement, is global.
In general, it's quite easy to forget the
var statement, and introduce a global variable.
For example, when you make a typo:
(A tip: the
prod variable has a typo in the loop.)
Yes, that's sucks. :-(
Use local variables, whenever it's possible.
Declare all your local variables at the beginning of your functions.
In ES 6, there are new ways to use local variables.
Function arguments are values passed to the function during a function call.
n is an argument.
In general, arguments can be passed by value, and by reference.
undefined) are passed by value.
While passing an argument by value, a copy of the value is made, and the copy is passed to the function.
It means, that the function may change the passed value, and it won't affect the original value.
As long, as you pass a primitive value to the function, you can do whatever you want with the value, and it won't affect the original variable.
On the other hand, not primitive values are passed by reference.
Arrays and objects are not primitive values.
It means, that they can be changed in the function's body.
And what when you don't pass some arguments?
When an argument is not passed, it's
This feature can be used to set default values for arguments.
undefined (since it hasn't been passed), it will be set to
(In ES 6, there are other ways to use default values. It will be discussed in the advanced part of this guide.)
(Regardless of the number of declared arguments.)
All the passed arguments are available in the
arguments object looks like an array, it's not an array.)
It means, that functions are also objects.
And they can be passed as functions' arguments, just as any other objects.
But functions don't need any names:
In ES 6, the fat arrow syntax allows to create anonymous functions easier.
What would happen, if we defined a function within a body (scope) of another function?
showMsg function is defined in the body of the
showMsg function, the
text variable is used.
This variable is defined in the scope of the
We say, that the
showMsg function closes over the variables
Thus, it is called a closure.
What's so great about closures?
They encapsulate variables.
In a closure's body, all the enclosed variables are available.
But if we have a closure, we cannot touch them!
Which raises another question:
Is it possible to have a closure?
Let's analyse the code:
This is a variable definition:
Whatever is in the perenthesis, cannot be touched from outside.
This is a function in the parenthesis:
It's an anonymous function.
After the perenthesis, the function is called.
module variable will be bound the value returned by the function.
The returned value is an object, with one property:
greet property is a closure!
greet has access to the
This variable is inaccessible for the user of the
counter variable is private for the
Anonymous functions and closures are used:
The standard way:
Using a function as the returned value:
Functions returning other functions are called higher-order functions.
We have a function, that takes multiple arguments.
Then, we transform this function into a sequence of functions, which takes only one argument.
What we did to the
addPrefix function, was currying.
After currying, calling functions changes:
Currying can be used for ease creation of functions.
API is short for "application's programmer's interface".
For this guide, function's API is its signature: the name and arguments (both number and order).
Why is it important to design a good API?
The better API, the easier it is to use, understand and maintain.
The general rule: make up some convention and stick to it.
The following examples are just proposals.
Does the function do something? Use a verb.
Does the function returns something? Use a noun.
Camel case or dashes?
No arguments = no problem.
One argument = no problem.
More arguments = you have to think about it.
What's the problem?
The order of arguments, of course!
No currying: the least changing argument should come last.
Now, let's consider this:
We can easily drop the second argument.
If we use some reasonable default, we can make our job easier.
Currying: the least changing argument should come first.
Now, let's consider this:
We can easily create a function with a fixed value for the first argument.
If we use some reasonable (default) value, we can make our job easier.
Good luck with remembering the order of flags...
arguments object is no longer needed.
It is also possible with arrays:
let lets you define variables in a block scope.
No more worries about
vars visible in whole function!