What can you pass to a function as a parameter?

👨‍💻 Frontend Developer 🟡 Often Asked 🎚️ Easy
#JavaScript #Functions #JS Basics

Brief Answer

In JavaScript, you can pass any data types to a function:

  • Primitives: numbers, strings, boolean, null, undefined, symbol, bigint
  • Objects: arrays, objects, dates, regular expressions
  • Functions: both regular functions and arrow functions
  • Classes and constructors

All parameters are passed by value, but for objects a reference to the object is passed.


Detailed Comparison

Parameter TypePassing MethodCan ModifyExample
PrimitivesBy valueNofunction(5, "text", true)
ObjectsBy referenceYesfunction({name: "Alex"})
ArraysBy referenceYesfunction([1, 2, 3])
FunctionsBy referenceYesfunction(callback)
ClassesBy referenceYesfunction(MyClass)

What is passing by value and by reference?

Passing by value — a copy of the value is created, changes inside the function don’t affect the original.

Passing by reference — a reference to the object is passed, changes inside the function affect the original.

// Primitive - by value
function changePrimitive(num) {
  num = 100;
}
let x = 5;
changePrimitive(x);
console.log(x); // 5 (unchanged)
 
// Object - by reference
function changeObject(obj) {
  obj.name = "Changed";
}
let user = { name: "Alexander" };
changeObject(user);
console.log(user.name); // "Changed"

Examples

Primitive Types

function processData(number, text, flag, empty, undef) {
  console.log(typeof number); // "number"
  console.log(typeof text);   // "string"
  console.log(typeof flag);   // "boolean"
  console.log(typeof empty);  // "object" (null)
  console.log(typeof undef);  // "undefined"
}
 
processData(42, "Hello", true, null, undefined);

Objects and Arrays

function handleData(user, numbers, date) {
  console.log(user.name);        // "Alexander"
  console.log(numbers.length);   // 3
  console.log(date.getFullYear()); // current year
  
  // Modify object
  user.age = 30;
  numbers.push(4);
}
 
let person = { name: "Alexander" };
let arr = [1, 2, 3];
let now = new Date();
 
handleData(person, arr, now);
console.log(person.age);  // 30 (changed!)
console.log(arr.length);  // 4 (changed!)

Functions as Parameters (Callbacks)

function processArray(array, callback) {
  const result = [];
  for (let item of array) {
    result.push(callback(item));
  }
  return result;
}
 
// Pass function as parameter
const numbers = [1, 2, 3, 4, 5];
const doubled = processArray(numbers, x => x * 2);
console.log(doubled); // [2, 4, 6, 8, 10]
 
// Pass named function
function square(x) {
  return x * x;
}
const squared = processArray(numbers, square);
console.log(squared); // [1, 4, 9, 16, 25]

Classes and Constructors

class User {
  constructor(name) {
    this.name = name;
  }
  
  greet() {
    return `Hello, I'm ${this.name}!`;
  }
}
 
function createInstance(Constructor, ...args) {
  return new Constructor(...args);
}
 
// Pass class as parameter
const user = createInstance(User, "Alexander");
console.log(user.greet()); // "Hello, I'm Alexander!"
 
// Pass built-in constructor
const date = createInstance(Date, 2024, 0, 1);
console.log(date.getFullYear()); // 2024

Special Cases

Parameter Destructuring

// Object destructuring
function greetUser({ name, age = 18 }) {
  return `Hello, ${name}! You are ${age} years old.`;
}
 
const user = { name: "Alexander", age: 30 };
console.log(greetUser(user)); // "Hello, Alexander! You are 30 years old."
 
// Array destructuring
function processCoordinates([x, y, z = 0]) {
  return { x, y, z };
}
 
const coords = [10, 20];
console.log(processCoordinates(coords)); // { x: 10, y: 20, z: 0 }

Rest Parameters

function sum(...numbers) {
  return numbers.reduce((total, num) => total + num, 0);
}
 
console.log(sum(1, 2, 3, 4, 5)); // 15
console.log(sum(10, 20));        // 30
 
// Mixed parameters
function logMessage(level, ...messages) {
  console.log(`[${level}]:`, ...messages);
}
 
logMessage("INFO", "User", "logged", "into", "system");
// [INFO]: User logged into system

Default Values

function createUser(name = "Anonymous", age = 18, isActive = true) {
  return { name, age, isActive };
}
 
console.log(createUser());                    // { name: "Anonymous", age: 18, isActive: true }
console.log(createUser("Alexander"));         // { name: "Alexander", age: 18, isActive: true }
console.log(createUser("Maria", 25, false)); // { name: "Maria", age: 25, isActive: false }

Practice Tasks

Task 1: What will the console output?

function modifyValues(a, b) {
  a = 100;
  b.value = 100;
}
 
let num = 5;
let obj = { value: 5 };
 
modifyValues(num, obj);
console.log(num, obj.value);
Answer 5 and 100 — primitive `num` didn't change (passed by value), but object property `obj.value` changed (passed by reference).

Task 2: What will happen?

function processArray(arr) {
  arr = [1, 2, 3];
  return arr;
}
 
let original = [4, 5, 6];
let result = processArray(original);
console.log(original, result);
Answer [4, 5, 6] and [1, 2, 3] — reassigning parameter `arr` doesn't affect the original array, a new array is created.

Task 3: What will the console output?

function test(callback) {
  return callback(10, 20);
}
 
const result = test((a, b) => a + b);
console.log(result);
Answer 30 — arrow function `(a, b) => a + b` is passed as parameter and called with arguments 10 and 20.

Task 4: What will happen?

function createObjects(Constructor, count) {
  const objects = [];
  for (let i = 0; i < count; i++) {
    objects.push(new Constructor(`Object ${i}`));
  }
  return objects;
}
 
class Item {
  constructor(name) {
    this.name = name;
  }
}
 
const items = createObjects(Item, 3);
console.log(items.length);
Answer 3 — class `Item` is passed as parameter, 3 instances of the class are created.

Task 5: What will the console output?

function greet({ name, age = 25 }) {
  return `${name} (${age} years old)`;
}
 
console.log(greet({ name: "Alexander" }));
console.log(greet({ name: "Maria", age: 30 }));
Answer "Alexander (25 years old)" and "Maria (30 years old)" — destructuring with default value for `age`.

Task 6: What will happen?

function calculate(...numbers) {
  return numbers.filter(n => typeof n === 'number').reduce((sum, n) => sum + n, 0);
}
 
console.log(calculate(1, "2", 3, null, 4, undefined, 5));
Answer 13 — rest parameters collect all arguments into an array, only numbers are filtered (1, 3, 4, 5), their sum equals 13.

Practical Tips

1. Use Destructuring for Objects

// Bad
function createUser(userObj) {
  const name = userObj.name;
  const age = userObj.age;
  const email = userObj.email;
  // ...
}
 
// Good
function createUser({ name, age, email }) {
  // name, age, email are immediately available
}

2. Set Default Values

function processData(data = [], options = {}) {
  const { sort = true, limit = 10 } = options;
  // safe work with parameters
}

3. Be Careful with Object Mutation

// If you don't want to&nbsp;change the&nbsp;original
function processArray(arr) {
  const copy = [...arr]; // create copy
  copy.push('new element');
  return copy;
}
 
// For objects
function updateUser(user) {
  return { ...user, lastUpdated: new Date() }; // return new object
}

Summary

In JavaScript, you can pass any data types to a function:

  • Primitives are passed by value (copied)
  • Objects are passed by reference (can be modified)
  • Functions can be passed as callbacks
  • Classes can be passed as constructors

Important to remember:

  • Changing primitives inside a function doesn’t affect the original
  • Changing object properties affects the original
  • Reassigning a parameter doesn’t affect the original variable

Understanding what and how you can pass to functions is the foundation for writing flexible and reusable code!


Want more articles on interview preparation? Subscribe to EasyAdvice, bookmark the site and improve yourself every day 💪