Here we look at: What is a JavaScript function, defining a function, function hoisting, first-class function, function signatures, and function types.
Introduction
Functions are vital to any programming language. The concept of isolating and/or organizing small pieces of code into subroutines have many uses and values. Thereby, it has helped us structure medium to large programs, to reduce repetition, and modularize programs and/or subprograms from each other.
That’s why this article will tackle the JavaScript function in depth. Moreover, if you are coming from an object-oriented language like C#, Java, and/or C/C++, reading this article will definitely help you. One reason is because of my .NET background and the class-minded way of thinking when it comes to C# programming.
Table of Contents
What is a JavaScript Function?
Within the language of JavaScript, functions are objects. Objects? Yes, it is true. Let us see the proof below:
function laugh() {
return "hahahahaha";
}
console.log(typeof(laugh));
console.log(laugh instanceof Object);
console.log(laugh instanceof Function);
Let us see, what the ECMAScript language specification has to say regarding the JavaScript function. See the screenshot below or you can visit and see it here.
Acknowledging that a JavaScript function is an object. And, I know you are questioning, how does the JavaScript language distinguishes a function from an object? But before answering that, let me explain something. The JavaScript language defines many internal properties for objects, these internal properties are designated by a double square bracket “[[]]
” notation.
What do these internal properties have got to do with JavaScript functions? These internal properties can distinguish a function from an object, and this property is [[Call]]
. Moreover, this [[Call]]
property is unique to functions and indicates that the object can be executed. Thereby, [[Call]]
property is exclusive for functions. That’s why, when using the typeof
operator, it returns “function” .
Again, because functions are objects. And, they behave differently compared to other programming languages. Therefore, a good understanding of JavaScript function is imperative.
Defining a Function
Function Declaration
A function declaration begins with the function
keyword, plus the name of the function. Lastly, the contents (also known as code block) of the function are enclosed in curly braces. Let us see an example below.
function smile(happythought1, happythought2) {
return "My happy thoughts are " + happythought1 + " and " + happythought2;
}
Function Expression
A function expression doesn’t require a name after a function
keyword. Moreover, these functions are considered anonymous functions because the function itself has no name. And, it is referenced by a variable or property name.
Let us see an example below:
const smileAgain = function (happythought1, happythought2) {
return "My happy thoughts are " + happythought1 + " and " + happythought2;
};
The sample code above actually assigns a function value to the variable smileAgain
. As you can see, the function expression is pretty similar to the function declaration, with one exception the missing name and the semicolon at the end. More of their differences in the hoisting section.
Arrow Function
Recently, the ES6 version of JavaScript has introduced the arrow function. And, characterized as “=>
” (looks like an arrow to me!). Moreover, it gives us the ability to have a shorter syntax. Therefore, it behaves like the function expression but looks different because of the combinations of arrow operator and lambda expression.
Here are the things needed to remember about arrow functions:
- It consists of zero or more parameters that surround within an open and close parenthesis also known as round brackets
()
. - It is followed by the
=>
operator - After the arrow operator, it followed by a function body. Just remember, the body only needs to be enclosed by curly braces
{}
if there’s more than one expression. Therefore, you can omit the curly braces if there’s only one expression.
See the snippet below:
var showFavoriteLanguage(language) {
return `I love ${language}`;
}
const showFavoriteLanguage= (language) => `I love ${language}`;
In this section, let’s convert a function declaration into an arrow function. First, let’s define a function.
function getProductOfTwoNumbers(num1, num2) {
return num1 * num2;
}
Second, convert it into an arrow function.
const getProductOfTwoNumbers = (num1, num2) => {
return num1 * num2;
}
Looks like a function expression. Right? Want some style? We can remove the curly braces.
const getProuductOfTwoNumbers = (num1, num2) => num1 * num2;
Great! Looks good to me.
If you are curious, what if we only have one parameter? Let us see an example below.
const getFirstElement = (arr) => arr[0];
const squareNum = (num) => Math.pow(num, 2);
Function Hoisting
In the previous section, we have seen how to define a function
. Moreover, we have seen how similar the function declaration & function expression but differs in some ways.
Function declarations are hoisted to the top. Thereby, you can define a function after it’s used in code without causing an error.
Let us see an example below:
console.log(chuckle());
function chuckle() {
return "Hehehehe";
}
Remember that function hoisting happens exclusively for function declarations. One reason, the function’s name was identified in advance. While, function expression (including arrow function), can’t be hoisted because it is referenced only through a variable.
Attributes Of A First-class Function
This is what makes JavaScript functions powerful. Because the JavaScript language has first-class functions. And, according to MDN (Mozilla Developer Network):
“A programming language is said to have First-class functions when functions in that language are treated like any other variable. For example, in such a language, a function can be passed as an argument to other functions, can be returned by another function and can be assigned as a value to a variable.”
And, you can look it up here.
Here are some examples:
- Assign a function to a variable:
const love = function () {
return "I love JavaScript";
}
console.log(love());
- Add function to objects:
const sayHello = function (name) {
return "Hi! My name is " + name;
}
const customer = {
name: "Jin Vincent N. Necesario",
sayHello: sayHello
};
let name = customer.name;
console.log(customer.sayHello(name));
- Pass function to other functions as arguments:
function sayFavorite() {
return "Hi! My Favorite programming language is ";
}
function favoriteLanguage(func1, language) {
return func1() + language;
}
console.log(favoriteLanguage(sayFavorite, "JavaScript"));
- Return function from another function:
function followYou() {
return function () {
return "Your part of me I can't let go!!!";
};
}
const follow = followYou();
console.log(follow());
Function Signatures
Overloading
If you are coming from a static language like C#, Java, and/or C/C++, these languages support function overloading. And, it is the ability of a single-function to have multiple signatures. Moreover, a function signature is composed of a function name, the number of parameters, and the type of parameters the function accepts. However, the JavaScript language functions don’t have signatures. Therefore, JavaScript lacks function overloading.
Let us try to see what happens when we try to declare two functions with the same name.
function giveLove(act){
console.log(act);
}
function giveLove() {
console.log("Trust your partner");
}
giveLove("Love and trust your partner");
Based on the example we have, if you are coming from an object-oriented language, you’ll be expecting that the output should be "Love and trust your partner"
. And, because JavaScript lacks overloading, it executed the function that doesn’t have a parameter. Thus, the output is "Trust your partner"
.
Parameters
Another concept to understand is that JavaScript functions can pass any number of parameters without causing an error. This is because function parameters are stored as an “Array-like Object” called arguments.
If you like to read more about array-like objects, you can visit here.
Moreover, arguments can grow to contain a number of values. The length
property determines how many values are present in that function. Lastly, arguments object is automatically available inside any function. Therefore, named parameters in a function exist essentially for convenience and don’t limit the number of arguments that a function can accept.
Let us see an example below:
function decidedToLove() {
let len = arguments.length,
messageResult = "",
counter = 0;
while (counter < len) {
messageResult += counter === 0 ? arguments[counter]: `,${arguments[counter]}`;
counter++;
}
return messageResult;
}
console.log(decidedToLove("I'm in love"));
console.log(decidedToLove("Don't be mean", "Leave my heart alone"));
console.log(decidedToLove("love", "trust", "appreciate"));
Default Parameters
Default Parameters Prior to ES6
Prior to ES6, there was no clear way to assign default values to function parameters. Thereby, developers can check the parameters before assigning the default values to them.
Let us see an example below:
function yourAmazing(arg1, arg2, arg3) {
arg1 = arg1 || "arg1";
arg2 = arg2 || "arg2";
arg3 = arg3 || "arg3";
return `${arg1}, ${arg2}, ${arg3}`;
}
console.log(yourAmazing());
console.log(yourAmazing("my-first-argument"));
console.log(yourAmazing("my-first-argument", "my-second-argument"));
console.log(yourAmazing("my-first-argument", "my-second-argument", "my-third-argument"));
Let us see another example, this time checks if the argument passed is undefined or not.
function areYouAnAngel(arg1, arg2, arg3) {
arg1 = arg1 === undefined ? 1 : arg1;
arg2 = arg2 === undefined ? 2 : arg2;
arg3 = arg3 === undefined ? 3 : arg3;
return `${arg1}, ${arg2}, ${arg3}`;
}
console.log(areYouAnAngel());
console.log(areYouAnAngel("my-first-argument"));
console.log(areYouAnAngel("my-first-argument", "my-second-argument"));
console.log(areYouAnAngel("my-first-argument", "my-second-argument", "my-third-argument"));
Default Parameters ES6
Recently, the JavaScript language has a new syntax that can do a default parameter in an easier and elegant way. Hooray!
- Example of default parameter:
function myGifts(gift1 = "health", gift2 = "wealth", gift3 = "love") {
return `${gift1}, ${gift2}, ${gift3}`;
}
console.log(myGifts());
console.log(myGifts("healthy body"));
console.log(myGifts("healthy body", "cash-flow"));
console.log(myGifts("healthy body", "cash-flow", "family"));
- Passing an undefined value to your default parameter:
function youAreGreat(talent1 = 'write', talent2 = 'speak', talent3 = 'code') {
return `${talent1}, ${talent2}, ${talent3}`;
}
console.log(youAreGreat());
console.log(youAreGreat("read and write", undefined, undefined));
console.log(youAreGreat(undefined, "teach and speak", undefined));
console.log(youAreGreat(undefined, undefined, "write books"));
- Using an expression within your default parameter:
function myCashGifts(gift1 = 1000, gift2 = 2000,
gift3 = (Math.random() * (5000 - 1000) + 1000)) {
return `Your total cash: $${gift1 + gift2 + gift3}`;
}
console.log(myCashGifts());
Function Type
Again, JavaScript functions are objects. Therefore, functions have properties and methods just like other objects. Let us see what we can do with these properties and methods.
Function Properties
- The
length
property determines the total arguments in a function. - The
prototype
property references the actual function object.
Let us see an example of function-properties:
function setGift(gift1, gift2) {
return `My gifts this coming Christmas are ${gift1} and ${gift2}`;
}
console.log(setGift.length);
console.log(setGift.prototype);
Function Methods
The this Object
All scope in JavaScript has a this
object that represents the calling object for the function. For instance, within the global scope, this
represents the global object (window
). Moreover, once a function is called while attached to an object, the value of this
is equal to that object by default. Therefore, you can reference this
instead of directly referencing the object inside your method.
Let us see an example below:
function showFullName() {
console.log(this);
console.log(this.name);
}
const name = "Jin Vincent Necesario";
const person = {
name: "Jin Necesario",
showFullName: showFullName
}
const pet = {
name: "Bruno",
showFullName: showFullName
}
showFullName();
person.showFullName();
pet.showFullName();
Understanding the this
value of functions is key to good object-oriented programming in JavaScript. Three methods that permit you to change the value of this
and these are call
, apply
, and bind
methods.
The apply()
and call()
methods are almost the same when you want to manipulate the value of this
. The only difference is that apply()
needs array-like objects, whereas call()
needs to pass the object that acts as this
and needed arguments. Let us see them one by one with examples.
The call() Method
function showFullName(caller) {
return `Caller: ${caller} having a value of ${this.name}`;
}
window.name = "Jin Vincent Necesario";
const person = {
name: "Jin Necesario"
}
const pet = {
name: "Bruno"
}
console.log(showFullName.call(this.window, "global, the window object"));
console.log(showFullName.call(person, "person variable"));
console.log(showFullName.call(pet, "pet variable"));
The apply() Method
function showFullName(caller, param1) {
return `${param1}. The caller: ${caller} having a value of ${this.name}.`;
}
window.name = "Jin Vincent Necesario";
const person = {
name: "Jin Necesario"
}
const pet = {
name: "Bruno"
}
console.log(showFullName.apply(this.window, ["global, the window object", "Hi!"]));
console.log(showFullName.apply(person, ["person variable", "Hello!"]));
console.log(showFullName.apply(pet, ["pet variable", "Good day!"]));
The bind() Method
If you want a new function instance whose this
value is bounded to an object that you have provided. Let us see an example below:
const bike = {
speed: 10,
start: function () {
return `${this.speed} Km/h`;
}
};
const motorcycle = {
speed: 40,
start: function () {
return `${this.speed} Km/h`;
}
}
let upgradeBike = bike.start.bind(motorcycle);
console.log(upgradeBike());
Summary
In this post, we have discussed a number of concepts regarding JavaScript functions. We started by answering: what is a JavaScript function, how to define a function, why JavaScript is a first-class function. Lastly, we have looked at function signatures and function types.
I hope you have enjoyed this article, as I have enjoyed writing it. Stay tuned for more. Until next time, happy programming! Please don’t forget to follow/subscribe, bookmark, like, and/or comment. Cheers! And thank you!