DEV Community

Cover image for 🎸 JavaScript Functions: The VIPs of First-Class Objects
Anik Sikder
Anik Sikder

Posted on

🎸 JavaScript Functions: The VIPs of First-Class Objects

If JavaScript were a party, numbers would be sipping juice, strings would be chatting in the corner, objects would be showing off their keys…
and then the functions would show up.
Not only do they dance 💃 they own the party.

Why?
Because in JavaScript, functions are first-class objects.
And once you get that, the language suddenly feels smoother, more powerful, and way more fun.


🥇 What “First-Class” Really Means

“First-class” isn’t a marketing buzzword, it’s a nerdy way of saying:

You can treat functions just like any other value.

That means you can:

  • Store them in variables
  • Put them inside objects and arrays
  • Pass them to other functions
  • Return them from functions
  • Attach properties to them (yep, functions are objects!)

Let’s see that in action:

function greet(name) {
  return `Hello, ${name}!`;
}

const sayHello = greet;             // assign to variable
const toolbox = { hi: greet };      // store in object

function loud(fn, name) {           // pass as argument
  return fn(name).toUpperCase();
}

function greeter(prefix) {          // return a function
  return function(name) {
    return `${prefix} ${name}`;
  };
}

console.log(sayHello("Anik"));             // Hello, Anik!
console.log(loud(greet, "Anik"));          // HELLO, ANIK!
console.log(greeter("Welcome")("Anik"));   // Welcome Anik
Enter fullscreen mode Exit fullscreen mode

Boom. Functions doing yoga: stretchable, flexible, composable.


📦 Functions Are Objects (With Superpowers)

Here’s the twist: functions in JS are just special kinds of objects.

function hello() {
  console.log("Hi there!");
}

hello.language = "English";
console.log(hello.language); // English
Enter fullscreen mode Exit fullscreen mode

This means you can stick properties on them like Post, it notes.
It’s not something you’ll use every day, but it shows just how “objecty” functions are.


⚡ Arrow Functions: Tiny Functions on the Fly

Arrow functions are JavaScript’s version of quick sticky notes.

const square = x => x * x;
console.log(square(5)); // 25
Enter fullscreen mode Exit fullscreen mode

They’re great for short glue code, especially inside helpers like map, filter, and reduce.

Example: cleaning price strings.

const prices = ["$12.99", "$5.50", "$100.00"];
const toNumber = s => parseFloat(s.replace("$", ""));
const clean = prices.map(toNumber);

console.log(clean); // [12.99, 5.5, 100]
Enter fullscreen mode Exit fullscreen mode

When to avoid arrow functions?
If the logic needs a name, multiple steps, or a docstring like explanation, use function instead.


🔀 Sorting with Functions

JavaScript’s .sort method loves functions.

const products = [
  { name: "Keyboard", price: 59.99 },
  { name: "Mouse", price: 25.00 },
  { name: "Monitor", price: 199.00 },
];

// Sort by price ascending
const byPrice = [...products].sort((a, b) => a.price - b.price);

// Sort by name length, then alphabetically
const byLenThenName = [...products].sort((a, b) => {
  const lenDiff = a.name.length - b.name.length;
  return lenDiff !== 0 ? lenDiff : a.name.localeCompare(b.name);
});

console.log(byPrice);
console.log(byLenThenName);
Enter fullscreen mode Exit fullscreen mode

🤹 Fun trick: “shuffle” with sort.

const data = [1, 2, 3, 4, 5];
const randomized = [...data].sort(() => Math.random() - 0.5);

console.log(randomized);
Enter fullscreen mode Exit fullscreen mode

Not the fastest, but cute for quick hacks.


🧠 Closures: Functions With a Backpack

Closures are where functions get magical.
They can remember the variables from the place they were born like carrying a backpack 🎒.

function outer() {
  let count = 0;
  return function inner() {
    count++;
    return count;
  };
}

const counter = outer();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
Enter fullscreen mode Exit fullscreen mode

Even though outer is finished, inner remembers count.
This is the foundation for private variables, memoization, and stateful logic in JS.


🔍 Introspecting Functions

You can peek at a function’s insides.

function priceWithTax(price, rate = 0.15) {
  return +(price * (1 + rate)).toFixed(2);
}

console.log(priceWithTax.name);   // "priceWithTax"
console.log(priceWithTax.length); // 1 (only required params)
console.log(priceWithTax.toString());
// Shows the function source code
Enter fullscreen mode Exit fullscreen mode

Not as fancy as Python’s inspect, but enough to do cool metaprogramming tricks.


🛠 Higher-Order Functions

A higher-order function is just one that takes or returns a function.

Examples you use every day:

const numbers = [1, 2, 3, 4];

const doubled = numbers.map(n => n * 2);      // map
const evens = numbers.filter(n => n % 2 === 0); // filter
const sum = numbers.reduce((acc, n) => acc + n, 0); // reduce

console.log(doubled); // [2, 4, 6, 8]
console.log(evens);   // [2, 4]
console.log(sum);     // 10
Enter fullscreen mode Exit fullscreen mode

That trio map, filter, reduce is JavaScript’s assembly line.


🧮 Reduce: Folding Sequences

.reduce deserves its own spotlight.

const transactions = [100, -20, -5, 50];
const balance = transactions.reduce((acc, t) => acc + t, 0);

console.log(balance); // 125
Enter fullscreen mode Exit fullscreen mode

Running totals, building objects, even word counts, you’ll see reduce everywhere.


🎨 Partial Application & Currying

JS doesn’t have functools.partial, but you can fake it with closures or bind.

function applyTax(rate, price) {
  return +(price * (1 + rate)).toFixed(2);
}

const vatBD = price => applyTax(0.15, price);
console.log(vatBD(100)); // 115
Enter fullscreen mode Exit fullscreen mode

Or with bind:

const vatBD2 = applyTax.bind(null, 0.15);
console.log(vatBD2(100)); // 115
Enter fullscreen mode Exit fullscreen mode

🎭 Real-World Patterns

  • Strategy pattern (choose behavior at runtime):
const strategies = {
  percent: (price, v) => price * (1 - v),
  flat: (price, v) => price - v,
};

function applyDiscount(kind, price, value) {
  return strategies[kind](price, value);
}

console.log(applyDiscount("flat", 100, 20));    // 80
console.log(applyDiscount("percent", 100, 0.1)); // 90
Enter fullscreen mode Exit fullscreen mode
  • Pipeline (compose functions):
const pipe = (...fns) => x => fns.reduce((v, f) => f(v), x);

const result = pipe(
  str => str.trim(),
  str => str[0].toUpperCase() + str.slice(1).toLowerCase(),
  str => `${str}!`
)("  hello  ");

console.log(result); // Hello!
Enter fullscreen mode Exit fullscreen mode
  • Event callbacks: Every addEventListener, every setTimeout, every Promise.then they all rely on first-class functions.

🎤 Wrap-Up

Functions in JavaScript aren’t just instructions they’re living, breathing citizens in your code:

  • They can be stored, passed, and returned.
  • They carry memory (closures).
  • They power async, functional programming, and design patterns.
  • They’re literally objects with a secret life.

So the next time you write a function, don’t just think of it as “code that runs.”
Think of it as a VIP guest at the JavaScript party always first-class, always in style. 🕺

Top comments (0)