YEP ! Good ‘ol Functions, very familiar, exists in all programming languages (or does it ?). Now JS does not have one single way of writing functions, it has a whole arsenal of them, lets see each of them one by one.

  • The standard way:
function greet(name){
	console.log(`Hello, ${ name }`);
}

greet("Nexus"); //prints "Hello, Nexus"

The very basic and old school way of writing functions, totally understandable and good to work with.


  • Anonymous Functions:
const greet = function(name){
	console.log(`Hello, ${ name }.`);
}

greet("Nexus"); //prints "Hello, Nexus"

In this way we do not name a function, hence “anonymous” ! Now the function in itself without any assignment to it will throw an error so a variable, const greet in this case, is required !

In JavaScript, Functions are first class members therefore they can be stored inside a variable ! This is the very first strange thing I found !


  • Arrow Functions (ES6+):
name => console.log(`Hello, ${ name }`); //function declared but not called

const greet = name => console.log(`Hello, ${ name }.`);

greet("Nexus"); //prints "Hello, Nexus"

Now this is the worst thing ! Just in order to make things look good and since JS treats functions as first class members, we can create an arrow function.

Arrow functions are a way to write anonymous functions but in a much cleaner way. But this cleanliness comes at the cost of readability ! Now this is a personal preference I am not used to see functions like this and also don’t like it either therefore it takes me some time to realize what’s actually happening.

Now these can be written in a more couple of ways based on number of arguments and number of lines in a function body.

NOTE: If a return statement is used inside a arrow function then {} must be used.

The above is a one arg, one line function !

Now lets see a multi arg, one line function !

const greet = (name, day) => console.log(`Hello, ${ name } ! Today is ${ day }.`);

greet("Nexus", "Sunday"); //prints "Hello, Nexus ! Today is Sunday."

To use multiple args we simply enclose them in brackets () !

Now lets see a multi arg, multi line function !

const greet = (name, day) => {
	console.log(`Hello, ${ name } ! Today is ${ day }.`);
	console.log("Tomorrow is Monday.");
	return;
}

greet("Nexus", "Sunday");

//prints:
/*
Hello, Nexus ! Today is Sunday.
Tomorrow is Monday.
*/

Just like the args, to have multi-line function body, we enclose the body in second brackets a.k.a. “curly braces” {} !


  • IIFE - Immediately Invoked Function Expression:
(function(name){
	console.log(`Hello, ${ name }.`);
})("Nexus");

This runs immediately ! IIFE does not need to be called separately, we define a blank function with our main function as a parameter and immediately call it using ().

(main Function body)(arg) <- This is the syntax for IIFE !

This is useful if needed to create a private scope or execute a body immediately.


this keyword and its behavior towards functions

The this keyword is the reference to the current object a function is being called on ! By default any function is called upon the global window object !

function show_this(){
    console.log(this);
}

show_this(); //shows the global window object

Here the function show_this() is called upon the Global Window Object (DOM) ! Therefore logging this will log the global window object !

Lets try to access a private value:

const obj = {
	val: 32,
	func: function(){ console.log(this.val); } //prints 32
}

obj.func();

Here func is called upon the obj object and val is private to obj ! Therefore, logging this.val prints the value of val that is inside obj (32 in this case !)


this behavior towards arrow functions

Now the this keyword behaves differently in case of arrow functions !

Any arrow function does not have a this ! Normally this will bind to a object the function is called upon but in arrow functions this does not happen, this always refers to the outer scope while being created i.e. this in arrow functions will always refer to either the Global Window Object or just be undefined !

const obj = {
	val: 32,
	func: () => console.log(this.val); //prints undefined
}

obj.func();

Callback Functions

Since Functions are treated as first class members in JS, they can also be passed as arguments to another functions. The function passed as a function to another function is called a Callback Function.

Even though sounds good it can get very very nasty !

function fun(callback){
	console.log("This runs before the callback function");
	callback();
}

const cb = () => console.log("I am a callback function");

fun(cb);

fun accepts a function as a parameter ! Its very cursed when I first saw that !

Now after passing a function as a param, we can call it anytime we want.

This is very useful in event handling, set timeouts and async programming. Ands its one of the main reasons functions are designed to be first class members in JS. But this can get quirky and bad if there are many callback nestings, Becomes impossible to read and manage.

Lets see:

function fun(callback){ //called by fun(cb)
	console.log("This runs before the callback function");
	callback(another_cb);
}

const cb = (callback) => {  //called by callback(another_cb) in fun
	console.log("I am a callback function");
	callback(yet_another_cb);
}

const another_cb = (callback) => { //called by callback(yet_another_cb) in cb
	console.log("I am another callback function");
	callback();
}

const yet_another_cb = () => console.log("I am yet another callback function"); //called in another_cb

fun(cb); //call the base function

I don’t even want to go any deeper, My brain already Hurts ! Don’t even ask me to explain this, I am hospitalized after writing and trying to understand this, Ask chatGPT or CoPilot ! 😭😭🤕🤕

THIS IS A PRIME EXAMPLE OF CALLBACK HELL ! Don’t do this, this is BAD !

Just in case, this is a more clear look of how it looks:

fun(cb)
	cb(another_cb)
		another_cb(yet_another_cb)
			yet_another_cb()  //this is maddening

If there is still ambiguity, callback hell is when u call a function inside another function and call another function inside that function and then continue to go down like that !


This is it for function quirks !

Check out other JS quirks here: Quirk Index