
In this post i will demonstrate what the function expression is, how to create and call it and also i will show another shorthand type of it which is the arrow functions.
Function Expressions
A function expression in javascript is the same as anonymous function or function with no name except that the function expression has a name:
 anonymous function
// anonymous function with no name var func = function() { }
function expression gives the ability to give the function a name like this:
// function expression var func = function my_name(param1, param2, ...paramN) { // function name "my_name" // i can access the function name here }
The function expression name is optional and is used only locally inside the function body for example if you want to write a recursive function using function expressions then you must supply the function name. function name can’t be used in the outer scope, instead to call the function you use the variable that you assign the function to like that:
// calling the function expression func(); // however note if you call it with the name you get an error my_name(); // not valid
Let’s see a simple example to demonstrate the function expression, in this example i build a hierarchical list such as a navigation bar so consider we have this array:
let data = [ { title: 'Home' }, { title: 'Services', subitems: [ { title: 'Web development' }, { title: 'Web Design' }, { title: 'Marketing' }, { title: 'Other Services', subitems: [ { title: 'Website hosting', subitems: [ { title: 'Linux hosting' }, { title: 'Windows hosting' } ] }, { title: 'Support' }, { title: 'Maintainance' } ] } ] }, { title: 'About us', subitems: [ { title: 'About' }, { title: 'Why us' }, { title: 'Our Team' }, { title: 'Our Mission' }, ] }, { title: 'Contact us' } ];
Now we need to write a function to loop over this array and build an html nested unordered list, so we use the function expression:
let menu_builder = { build: function tree(items) { // function expression let menu = '<ul>'; for(var i = 0; i < items.length; i++) { menu += '<li>' + items[i].title + '</li>'; if(items[i].hasOwnProperty('subitems')) { menu += tree(items[i].subitems); // calling function recursively using the name } } menu += '</ul>'; return menu; } };
As shown above i write a function expression inside the object “menu_builder” and give it a name of “tree” to reference it recursively inside the function body.
Overall code
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title>function expression</title> <style> nav ul { display: inline-block; } nav ul li { list-style: disclosure-closed; color: red; } nav ul > li { color: red; } nav ul ul > li { color: green; } nav ul ul ul > li { color: blue; } </style> </head> <body> <nav id="nav_bar"></nav> <script> let data = [ { title: 'Home' }, { title: 'Services', subitems: [ { title: 'Web development' }, { title: 'Web Design' }, { title: 'Marketing' }, { title: 'Other Services', subitems: [ { title: 'Website hosting', subitems: [ { title: 'Linux hosting' }, { title: 'Windows hosting' } ] }, { title: 'Support' }, { title: 'Maintainance' } ] } ] }, { title: 'About us', subitems: [ { title: 'About' }, { title: 'Why us' }, { title: 'Our Team' }, { title: 'Our Mission' }, ] }, { title: 'Contact us' } ]; let menu_builder = { build: function tree(items) { let menu = '<ul>'; for(var i = 0; i < items.length; i++) { menu += '<li>' + items[i].title + '</li>'; if(items[i].hasOwnProperty('subitems')) { menu += tree(items[i].subitems); // note calling function recursivly using the name } } menu += '</ul>'; return menu; } }; document.getElementById("nav_bar").innerHTML = menu_builder.build(data) ; </script> </body> </html>
Â
Function expression name vs Anonymous function name
If you want to get the name of the of the function expression you can use the “name” property on the variable that variable expression is assigned to like this example:
var not_anonymous = function my_name() {}; console.log(not_anonymous.name); // output my_name
In contrast with the anonymous functions which returns “anonymous” as the name.
var anonymous_func = function() {}; console.log(anonymous_func.name); // output anonymous
Function expression hoisting
Function expressions not hoisted in other means you can not call a function expression before the actual expression declaration:
my_func(); TypeError: my_func is not a function var my_func = function show_alert() { alert(''); };
click here to learn more about javascript hoisting.
Function expressions can be in a shorthand form using arrow functions, this feature is supported in EcmaScript 2015, let’s see it in the next section.
Â
Arrow Functions
Arrow function is an alternative short form to the function expression we just saw and in it’s basic use takes this form:
() => { statements }
Can also take parameters:
(param1, param2, … paramN) => { statements }
If the function body is just one line the parentheses can be omitted:
(param1, param2, … paramN) => statement
The above expression equivalent to
(param1, param2, …, paramN) => { return expression; }
If there is only one parameter it can take this form
singleParam => { statements } // Parentheses omitted
Arrow function also supports rest spread operator
(param1, param2, ...rest) => { statements }
With default values
(param1 = default, param2, …, paramN) => { statements }
Â
Let’s see some examples using the arrow functions
Function without parameters
var show_alert = () => alert('demonstrating arrow functions'); show_alert();
Function with one parameter
var display_message = (msg) => console.log(msg); display_message('hello world'); // hello world
Or can be written also like this:
var display_message = msg => console.log(msg);
In case the function body in one statement then there is no need to parentheses:
var sum = (num1, num2) => num1 + num2; console.log(sum(10, 50)); // output: 60
previous example can be written also like this:
var sum = (num1, num2) => { return num1 + num2; }
The most common uses of arrow function is to use it as a callback to another function like this consider this classic example when listening to button click:
document.getElementById("btn-submit").addEventListener('click', function(event) { console.log('button is clicked!') })
This example uses the anonymous function we just described above and can be written in short form using arrow functions like this:
document.getElementById("btn-submit").addEventListener('click', (event) => console.log('button is clicked!'); );
Or like this:
document.getElementById("btn-submit").addEventListener('click', event => console.log('button is clicked!'); );
More examples on arrow functions:
let i = 0; setInterval(() => { console.log(i++); }, 1000); let countries = ['USA', 'Russia', 'China', 'Germany']; countries.map((item) => { return item.length; }); // output: [3, 6, 5, 7] countries.map(item => { return item.length; }); // output: [3, 6, 5, 7] countries.map(item => item.length); // output: [3, 6, 5, 7] // return countries having index 0 or 3 let filtered = countries.filter((item, index) => index == 0 || index == 3); console.log(filtered); // loop over filtered countries filtered.forEach(item => console.log(item));