DEV Community

PRIYA K
PRIYA K

Posted on

Functions in JavaScript

Functions

  • Reusable block of code designed to perform a specific task.
  • Fundamental building blocks in JavaScript.
  • ia similar to procedure -A set of statements to perform a task.
  • Procedure to qualify as a function , it Take inputs,perform action and return outputs
  • Use a function,define it somewhere in the scope
  • Allows to reuse,organise and modlarise code

Defining Functions or Function Declaration
A function definition (also called a function declaration, or function statement) consists of

  • the function keyword,
  • The name of the function.
  • A list of parameters to the function, enclosed in parentheses and separated by commas.
  • The JavaScript statements that define the function, enclosed in curly braces, { /* … */ }.
function functionName(parameters) {
  // code
}
Enter fullscreen mode Exit fullscreen mode

Example

function square(number) {
  return number * number;
}
Enter fullscreen mode Exit fullscreen mode

JavaScript passes values in two ways:
Primitive values (like number, string)
1.Passed by value
Means a copy is sent

function change(x) {
  x = 10;
}

let a = 5;
change(a);
console.log(a); // still 5
Enter fullscreen mode Exit fullscreen mode

Because only a copy of a is changed, not the original.

2.Objects & Arrays
*Passed by reference *
Means the function can modify the original data.
if the function changes the object's properties, that change is visible outside the function.

Example with Object:

function myFunc(theObject) {
  theObject.make = "Toyota";
}

const myCar = {
  make: "Honda",
  model: "Accord",
  year: 1998,
};

console.log(myCar.make); // "Honda"
myFunc(myCar);
console.log(myCar.make); // "Toyota"
Enter fullscreen mode Exit fullscreen mode

The original object changed

Example with Array:
When you pass an array as a parameter, if the function changes any of the array's values, that change is visible outside the function.

function myFunc(theArr) {
  theArr[0] = 30;
}

const arr = [45];

console.log(arr[0]); // 45
myFunc(arr);
console.log(arr[0]); // 30
Enter fullscreen mode Exit fullscreen mode

Array also changed outside the function

Function declarations and expressions can be nested, which forms a scope chain.
For example:

function addSquares(a, b) {
  function square(x) {
    return x * x;
  }
  return square(a) + square(b);
}
Enter fullscreen mode Exit fullscreen mode

Scope
Inner function can use outer function variables
Outer function cannot use inner function variables

Summary
Function = reusable block of code
Parameters = inputs
return = gives output
Primitive → copy (no change outside)
Object/Array → original can change
Functions can be inside other functions

What is a Function Expression?
You create a function and store it in a variable

const square = function (number) {
  return number * number;
};
Enter fullscreen mode Exit fullscreen mode

call it :

square(4); // 16
Enter fullscreen mode Exit fullscreen mode

Variable = square
Function = stored inside it

Anonymous Function (No name)

const square = function (number) {
  return number * number;
};
Enter fullscreen mode Exit fullscreen mode

Named Function Expression
A name is given:

const factorial = function fac(n) {
  return n < 2 ? 1 : n * fac(n - 1);
};
Enter fullscreen mode Exit fullscreen mode

Why give a name?
Helps in recursion (function calling itself)
Helps in debugging

factorial(3); // 6
Enter fullscreen mode Exit fullscreen mode

In Function Expression,Functions can be send as an Arguments to another function
using Map function

Functions can be passed like values!

function map(f, arr) {
  let result = [];
  for (let i = 0; i < arr.length; i++) {
    result[i] = f(arr[i]);
  }
  return result;
}
Enter fullscreen mode Exit fullscreen mode

Calling it:

const numbers = [0, 1, 2];

const cubes = map(function (x) {
  return x * x * x;
}, numbers);

console.log(cubes); // [0, 1, 8]

Enter fullscreen mode Exit fullscreen mode

We passed a function inside another function

Function Based on Condition

let myFunc;

if (num === 0) {
  myFunc = function (obj) {
    obj.make = "Toyota";
  };
}
Enter fullscreen mode Exit fullscreen mode

Function is created only if condition is true

*Function Constructor *
create functions from strings:

const add = new Function("a", "b", "return a + b");
Enter fullscreen mode Exit fullscreen mode

Unsafe (like eval())

What is a Method?
A method = function inside an object

const person = {
  name: "Priya",
  greet: function () {
    console.log("Hello");
  }
};

person.greet(); // Hello
Enter fullscreen mode Exit fullscreen mode

greet is a method

Summary
Function Declaration Function Expression
function add(){} const add = function(){}
Has name Can be anonymous
Loaded before execution Created at runtime

Function expression = function stored in a variable
Can be anonymous or named
Can pass functions as arguments
Can create functions inside conditions
Method = function inside object

What is “calling a function”?
Defining a function ≠ running it
You must call it to execute

function square(n) {
  return n * n;
}

Enter fullscreen mode Exit fullscreen mode

call it:

square(5); // 25
Enter fullscreen mode Exit fullscreen mode

When called:
5 goes into n
Function runs
Returns 25

Function must be in scope
*Hoisting *

square(5);

function square(n) {
  return n * n;
}
Enter fullscreen mode Exit fullscreen mode

Because function declarations are hoisted (moved up internally)

Passing Arguments
numbers
strings
objects
arrays

Example (Object)

function change(obj) {
  obj.name = "Priya";
}

let person = { name: "Anu" };
change(person);

console.log(person.name); // Priya
Enter fullscreen mode Exit fullscreen mode

Recursive Function (Function calling itself)
A function can call itself

Example: Factorial

function factorial(n) {
  if (n === 0 || n === 1) return 1;
  return n * factorial(n - 1);
}
Enter fullscreen mode Exit fullscreen mode

Calls:

factorial(5);
// 5 * 4 * 3 * 2 * 1 = 120
Enter fullscreen mode Exit fullscreen mode

Output:

console.log(factorial(5)); // 120
Enter fullscreen mode Exit fullscreen mode

Special Ways to Call Functions
** 1.call()**
Calls function with a specific object

function greet() {
  console.log(this.name);
}

const person = { name: "Priya" };

greet.call(person); // Priya
Enter fullscreen mode Exit fullscreen mode

2. apply()
Same as call(), but arguments in array

function add(a, b) {
  return a + b;
}

add.apply(null, [2, 3]); // 5
Enter fullscreen mode Exit fullscreen mode

In JavaScript:
Functions are objects
So they have methods like:
call()
apply()

Summary
Define ≠ execute
Call function using ()
Can pass any type as argument
Functions can call themselves (recursion)
call() and apply() help control how function runs

What is Hoisting?
Hoisting = JavaScript moves declarations to the top
So even if you write code later, JS behaves like it’s written at the top.

Function Declaration (Works with Hoisting )

console.log(square(5)); // 25

function square(n) {
  return n * n;
}

Enter fullscreen mode Exit fullscreen mode

So you can call the function before defining it

Function Expression (Does NOT work )

console.log(square(5)); // Error

const square = function (n) {
  return n * n;
};
Enter fullscreen mode Exit fullscreen mode

gives error:
ReferenceError: Cannot access 'square' before initialization

Why does this fail?
const square is not hoisted like a function
Only the variable name is reserved
The function is assigned later

So before assignment → it doesn't exist yet

*Comparison *
Type Hoisted? Can call before declaration?
Function Declaration Yes

Function Expression No

Function Declaration → Teacher writes answer on board before class starts
Function Expression → Teacher writes answer only when class reaches that point

Summary
Hoisting = moving declarations to top
Works for function declarations
Does NOT work for function expressions
That’s why one works before definition and one doesn’t

What is Recursion?
Recursion = a function calling itself
Instead of using loops (for, while), the function repeats itself.

A recursive function must have:

  1. Base condition (stop condition)
  2. Recursive call (call itself)
function count(x) {
  if (x >= 5) return;   // stop condition
  console.log(x);
  count(x + 1);         // function calls itself
}

count(0);
Enter fullscreen mode Exit fullscreen mode

Output
0
1
2
3
4

Recursion vs Loop
Loop:

let x = 0;
while (x < 5) {
  console.log(x);
  x++;
}
Enter fullscreen mode Exit fullscreen mode

Recursion:

function loop(x) {
  if (x >= 5) return;
  console.log(x);
  loop(x + 1);
}

loop(0);
Enter fullscreen mode Exit fullscreen mode

Both do the same thing!

Named Function Expression

const foo = function bar() {
  console.log("Hello");
  bar(); // or foo()
};
Enter fullscreen mode Exit fullscreen mode

Inside the function:
You can use bar() or foo() to call itself

Used for:
DOM traversal
File systems
Graphs

In recursion:
Because of stack (LIFO – Last In First Out)

Summary
Function calls itself → recursion
Must have base condition (otherwise infinite loop )
Uses call stack internally
Useful for trees, graphs, nested data
Recursion = repeat using function
Needs:
Stop condition
Self call

What is IIFE(Immediately Invoked Function Expressions )?
IIFE = a function that runs immediately after it is created

Syntax

(function () {
  // code runs immediately
})();
Enter fullscreen mode Exit fullscreen mode

Example
(function () {
console.log("Hello");
})();

Output:
Hello

No need to call it separately — it runs instantly

With Return Value

const value = (function () {
  return 10 * 2;
})();

console.log(value); // 20
Enter fullscreen mode Exit fullscreen mode

Function runs immediately and stores result in value

Why use IIFE?
1. Avoid variable pollution

(function () {
  let x = 10;
  console.log(x);
})();

// console.log(x); # Error
Enter fullscreen mode Exit fullscreen mode

x is not accessible outside
Keeps variables private

2.Creates its own scope
Variables inside IIFE don’t affect outside code

3.Useful for initialization

const result = (function () {
  let a = 5;
  let b = 10;
  return a + b;
})();
Enter fullscreen mode Exit fullscreen mode

Comparison
Normal Function:

function test() {
  console.log("Hi");
}
test();
Enter fullscreen mode Exit fullscreen mode

IIFE:

(function () {
  console.log("Hi");
})();
Enter fullscreen mode Exit fullscreen mode

No name, no separate call

IIFE is:
A function expression
Wrapped in ()
Called using ()

Summary
IIFE = function that runs immediately
No need to call it later
Creates private scope
Useful for one-time execution

What is Scope?
Scope = where a variable can be used

Function Scope
Variables inside a function are private

function test() {
  let x = 10;
  console.log(x); // works
}

test();
// console.log(x);  Error (not accessible outside)
Enter fullscreen mode Exit fullscreen mode

x exists only inside the function

Global Scope
Variables outside functions are global

let a = 5;

function show() {
  console.log(a); // can access
}

show();
Enter fullscreen mode Exit fullscreen mode

Functions can use global variables

Nested Functions

const name = "Chamakh";

function getScore() {

  let num1 = 2;
  let num2 = 3;

  function add() {
    return name + " scored " + (num1 + num2);
  }

  return add();
}

console.log(getScore()); // Chamakh scored 5
Enter fullscreen mode Exit fullscreen mode

Who can access what?
Inner function can access:

Its own variables
Parent function variables (num1, num2)
Global variables (name)
But outer function cannot access inner variables

Inside → can see outside
Outside → cannot see inside

What is Closure?
Closure = when a function remembers variables from its outer scope
Even after the outer function is finished!

Example of Closure

function outer() {
  let count = 0;

  function inner() {
    count++;
    console.log(count);
  }

  return inner;
}

const result = outer();

result(); // 1
result(); // 2
result(); // 3
Enter fullscreen mode Exit fullscreen mode

Why this works?
inner() remembers count
Even though outer() is already finished
This memory = closure

Why closures are useful?
Data privacy (like private variables)
Maintain state (remember values)
Used in real apps (timers, counters, event handlers)

Summary
Scope = where variables are accessible
Function scope = variables are private
Inner function can access outer variables
Closure = function remembers outer variables

Parameters
are placeholders defined in function definitions
Parameters are inputs to a function.
They act like variables inside the function.

Arguments
Pass the actual values when calling the function.

Example of Parameters

function greet(name){
   console.log("Hello",+ name);
}
greet("Alice");
Enter fullscreen mode Exit fullscreen mode

Explanation
name => is the parameter
Alice => is the argument

Default Parameters
No arguments is passed during the function call
if no value is passed,the function uses the 'default' value
Example

function greet(name = "Priya"){
    console.log("Hello",+ name);
}
greet();
greet(name);
Enter fullscreen mode Exit fullscreen mode

Return Statement
value can be stored in variable or used directly
when return executes,the function stops execution
Is used to send a result back from a function.

function add(a, b) {
  return a + b; // returns the sum
}

let result = add(5, 10);
console.log(result);
Enter fullscreen mode Exit fullscreen mode

Multiply-nested functions
You have functions inside functions:
A → contains B

B → contains C

Who can access what?
Child can see parent’s things
Parent cannot see child’s things

function A(x) {
  function B(y) {
    function C(z) {
      console.log(x + y + z);
    }
    C(3);
  }
  B(2);
}
A(1);
Enter fullscreen mode Exit fullscreen mode

Step-by-step
A(1) → x = 1
B(2) → y = 2
C(3) → z = 3

Inside C:
x = 1 (from A)
y = 2 (from B)
z = 3 (from C)

Output:
1 + 2 + 3 = 6

Why C can access everything?
Because of scope chaining

C can see:
its own variables (z)
parent function variables (y)
grandparent variables (x)

A (grandparent)
└── B (parent)
└── C (child)

C can see:
B’s data
A’s data

But:
A cannot see C
B cannot see inside C

Why?
Because C is inside B, and B is inside A

Name conflicts
Problem: Same variable name
When two arguments or variables in the scopes of a closure have the same name, there is a name conflict. More nested scopes take precedence. So, the innermost scope takes the highest precedence, while the outermost scope takes the lowest. This is the scope chain. The first on the chain is the innermost scope, and the last is the outermost scope.
when You have two variables named x

function outside() {
  const x = 5;        // outer x
  function inside(x) {  // inner x (same name)
    return x * 2;
  }
  return inside;
}
console.log(outside()(10));
Enter fullscreen mode Exit fullscreen mode

outside() runs → creates:

outer x = 5
It returns inside function
call:

inside(10)
so inside:

inner x = 10

Now inside this line:
return x * 2;

Which x is used?
outer x = 5
inner x = 10

Answer
Inner x is used (10)
10 * 2 = 20

Why?
Because of scope priority
Nearest (inner) variable is used first

Rule
If names clash → inner scope wins

Scope Chain
inside → outside → global

JavaScript checks:
inside scope
then outside (not needed)
then global

Using the arguments object
The arguments of a function are maintained in an array-like object.
Inside every function, JavaScript gives you a special object called:
arguments
It stores all values passed to the function

Think like this
Function = box

Arguments = items inside the box

Example

function test() {
  console.log(arguments);
}

test(10, 20, 30);
Enter fullscreen mode Exit fullscreen mode

Output:
[10, 20, 30]

How to use it
First argument → arguments[0]
Second → arguments[1]
Total count → arguments.length

Example

function show() {
  console.log(arguments[0]);
  console.log(arguments[1]);
  console.log(arguments.length);
}

show("A", "B", "C");
Enter fullscreen mode Exit fullscreen mode

Output:

A
B
3

Why is it useful?
When you don’t know how many inputs will come

Example

function myConcat(separator) {
  let result = "";

  for (let i = 1; i < arguments.length; i++) {
    result += arguments[i] + separator;
  }

  return result;
}
Enter fullscreen mode Exit fullscreen mode

Call:

myConcat(", ", "red", "orange", "blue");
Enter fullscreen mode Exit fullscreen mode

What happens

arguments[0] = ", "     (separator)
arguments[1] = "red"
arguments[2] = "orange"
arguments[3] = "blue"
Enter fullscreen mode Exit fullscreen mode

Loop starts from i = 1
Builds:
red + ", "
orange + ", "
blue + ", "

Output:
red, orange, blue,

arguments is NOT a real array
It has:
index (0,1,2…)
length

It does NOT have:

push()
pop()
map()

arguments = all inputs passed to a function

Instead of arguments, use:

function myFunc(...args) {
  console.log(args);
}

Enter fullscreen mode Exit fullscreen mode

args is a real array

Top comments (0)