Function is not a bizarre word to software developers. If your day to day activities involve even a little bit of coding, you must be ending up creating/modifying one or more functions before logging off for the day.
A function in a nutshell is nothing but a set of statements to perform some action. A function may have some input parameters (to be used in the function body) and may return a value after execution.
While JavaScript functions also have these characteristics, they are much more than just conventional functions. Functions in JavaScript are objects. You can go through my post on JavaScript objects where I mentioned that almost everything in JavaScript is an object.
Being an object, a JavaScript function may have properties and other functions (methods). Let’s have a look at a typical function definition in JavaScript.
function myNotSoGreatFunc(visitor) {
console.log("Welcome to Code Morning Mr. " + visitor);
}
That’s right. The function above doesn’t do anything great as it just welcomes the visitors on my blog. But it demonstrates what a JavaScript function looks like. A function definition starts with keyword function
followed by the function name with zero or more parameters in a parenthesis. Then actual function code (JavaScript statements) is wrapped inside a pair of curly braces { }
. A function can have an optional return
statement. A JavaScript function always returns a value. When there is no return
statement in the function
body, then function
returns undefined
.
The code below invokes the function passing visitor name as argument.
myNotSoGreatFunc("Bob Martin");
Until now, we have just seen the very basic characteristics of the functions. We will now take a closer look at some of the advanced concepts of JavaScript functions.
Anonymous Functions
A JavaScript function can be anonymous. That means you can omit the function name from a function declaration. However, the function must be stored in a variable.
var addNumbers = function (x, y) { return x + y; }
The above syntax is also referred to as function expression. You can treat the variable addNumbers
as function name and call the function as below.
var sum = addNumbers(2, 3);
Function expressions are handy when you want to pass a function as an argument to another function. Let’s try to understand this with a simple example.
var add = function (first, second) { return first + second };
var multiply = function (first, second) { return first * second };
function calculate(fun, a, b) {
return fun(a, b);
}
I have first created two anonymous functions. The first one returns the sum and the second one returns the multiplication of two numbers. Fairly simple, nothing to be proud of. Then, I have defined a function calculate
which accepts a function as first parameter followed by two more parameters to accept two numbers.
I can invoke the function calculate
by passing any function as first parameter.
var sum = calculate(add, 2, 3);
var multiplication = calculate(multiply, 2, 3);
You can see how easy it is to pass functions as arguments. This pattern is heavily used in AJAX when you pass callback functions to handle success or failure scenarios after completion of AJAX call.
More on Arguments
JavaScript is very flexible when it comes to passing or accessing function arguments. Let’s look at the ways function arguments can be manipulated.
Missing Arguments
A function can be called with fewer or more number of arguments than required. If you invoke a function with fewer arguments than declared, then missing arguments are set to undefined.
function callMe(a, b, c) {
console.log("c is " + typeof c);
}
callMe("Code", "Morning");
callMe("Learn", "JavaScript", "Functions");
Arguments Object
All JavaScript functions have a special object called arguments
which is an array of arguments passed during function invocation. This object can be used to access individual arguments or to get the total number of arguments passed to the function.
function callMe() {
var i;
for (i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
console.log("Total arguments passed: " + arguments.length);
}
This function assumes no arguments to be passed but as I said, you can pass any number of arguments to a function in JavaScript. I can call this function like this:
callMe("Code", "Morning", "Mr. Programmer");
Each argument can be accessed as an array item from arguments
object. The total number of arguments
passed to the function can be obtained from arguments.length
property.
Default Parameters
Are you a C++ or C# programmer? Have you seen the functions with default parameters? Probably yes! ECMAScript 6 brings this feature in JavaScript and this is how you can define a function with default parameters.
function greetMyVisitors(name, profession = "The cool programmer") {
alert("Welcome Mr. " + name + ", " + profession);
}
The function greets my blog visitors politely. It takes two parameters as name
and profession
and shows a welcome message in a message box. The second parameter takes a default value if no argument (or ‘undefined
’) is passed during invocation. See the illustrations.
greetMyVisitors("Justin Bieber", "The singer");
greetMyVisitors("Bob Martin");
greetMyVisitors("John Papa", undefined);
Nested Functions
A function may contain one or more functions inside of it. The inner functions may again contain functions inside and so on. Let’s see this in action.
function wakeUpAndCode() {
function wakeUp() {
console.log("I just woke up");
}
function code() {
console.log("I am ready to code now");
}
wakeUp();
code();
}
wakeUpAndCode();
The function wakeUpAndCode
contains two inner functions wakeUp
and code
. When wakeUpAndCode
is called, it starts executing the function body. There are only two executable statements in the outer function, the call to wakeUp
and code
methods. Call to wakeUp
will execute inner wakeUp
function which will write the string
“I just woke up
” to console. Call to code
will write “I am ready to code now
” string
to console.
Inner functions have access to variables and parameters of all outer functions. Inner functions are kind of private
implementation within a function and can’t be invoked from outside of the outer function. Use of inner functions gives birth to closures in JavaScript which I will discuss in a separate post.
Immediately Invoked Function Expression (IIFE, pronounced iffy)
An IIFE is an anonymous function expression which is invoked immediately. An IIFE looks like this:
(function() {
}());
All you have to do is create an anonymous function, put a pair of parentheses immediately after function definition to invoke the function and finally wrap all the code in another pair of parentheses. The outermost pair of parenthesis turns everything inside of it to an expression because parentheses can’t contain JavaScript statements. The pair of parentheses after function definition invokes the function immediately.
Any variables or functions defined within IIFE block are local to the block and it’s not possible for any code outside this scope to change them.
Have a look at this example of IIFE. The function will execute automatically without being called.
(function() {
console.log("I run on my own.");
}());
Just copy and paste the code in plunker and see the output in browser console. If you don’t know where to find browser console, then just press F12 in your browser window to bring the developer tools. Hop over to console tab to see all the outputs of console.log
statements.
IIFE are a nice way to create a local scope around your code. They help you protect your variables and functions from being changed or overridden by some other part of the application. What are the other advantages of IIFE in JavaScript? How they solve the problem of global scope pollution? Don’t forget to check my post on Immediately Invoked Function Expressions.
Constructor Functions
A function may act as a constructor and new objects can be created using the constructor function. This is one of the features that makes JavaScript object oriented. The advantage of using constructor function is that you will be able to create as many objects as you want with predefined properties and methods. If you are correlating this with classes and objects in other languages, then you are right.
Let’s create a constructor function Programmer
with some properties and methods. You can assume it as a class in your favorite language.
function Programmer(name, company, expertise) {
this.name = name;
this.company = company;
this.expertise = expertise;
this.writeCode = function() {
console.log("Writing some public static thing..");
}
this.makeSkypeCall = function() {
console.log("Making skype call..");
}
this.doSalsa = function() {
console.log("I'm a programmer, I can only do Gangnam style..");
}
this.canWriteJavaScript = function() {
return expertise === "JavaScript";
}
}
The function expects three arguments and creates an object with three properties and four methods. I don’t think the code above needs any explanation. I can create any number of programmer objects out of this.
var javaProgrammer = new Programmer("Mohit Srivastava", "Infosys", "Java");
var dotnetProgrammer = new Programmer("Atul Mishra", "Prowareness", ".NET");
While it’s also possible to create objects using object literal syntax with the same set of properties and methods, we need to write the same code multiple times which is not a great practice at all. If you know DRY principle of programming, you won’t deny agreeing with me. Constructor function makes it possible to define your object once and create real instances anytime you want.
Caution!
Always use new keyword to create new objects from constructor. Forgetting new
and trying to create an instance like this->
var jsProgrammer = Programmer("Douglas Crockford", "Yahoo", "JavaScript")
will end up adding all the properties and methods to global window
object which will be just horrible. The reason for this behavior is ‘this
’ points to global window
object unless specified explicitly. Using new
sets ‘this
’ context to the current object being created.
However, there is a workaround to overcome this problem. You may change your constructor implementation to make it scope-safe and then while creating new objects, you can happily ignore the new
keyword. See the modified constructor code below. I have removed some methods to make the illustration shorter.
function Programmer(name, company, expertise) {
if(!(this instanceof Programmer)) {
return new Programmer(name, company, expertise);
}
this.name = name;
this.company = company;
this.expertise = expertise;
this.writeCode = function() {
console.log("Writing some public static thing..");
}
}
The if
condition checks whether the this
object is an instance of Programmer
. If not, it creates a new Programmer
object and returns the same by calling the constructor again.
Note: You will not be able to create a new object from constructor in strict mode without using ‘new
’ keyword. Strict
mode enforces some coding guidelines and throws error in case you are writing something unsafe. To enable strict
mode, you just have to add the string
‘use strict
’ in the beginning of your code. It’s a good practice to run your code in strict
mode.
'use strict'
function doSomething() { ... }
....
....
I have covered pretty much everything about functions in this comprehensive post. Functions are said to be the first class citizens in JavaScript. Understanding functions is probably the most important thing if you want to master JavaScript.
I hope I haven’t made you scratch your head reading this essay-ish post and believe you got to know about functions in details. Please share the post if you liked it. If not, leave a comment to help me improve next time. See you sometime soon.
You might also be interested in: