JavaScript Fundamentals: Functions

Welcome to the third part of our Node.js Jumpstart series! In the previous article, we covered declaring variables. Now, let's dive into another core concept: functions—reusable blocks of code that perform specific tasks.


JavaScript Functions: Different Ways to Define Them

Below are three common patterns for defining functions in JavaScript:

Function Declarations

This is the traditional, named way to define a function.

// Syntax: function functionName(parameters) { ... }
function greet(name) {
  return `Hello, ${name}!`;
}

console.log(greet('AI bot')); // Output: Hello, AI bot!

In JavaScript Function declarations are hoisted, meaning they can be called before their definition.

// You can call it before the definition due to hoisting:
console.log(question('Ultron')); // Output: Hello, are you Ultron? (AI system created by Tony Stark and Bruce Banner)

function question(name) {
  return `Hello, are you ${name}?`;
}

Key Feature: Function declarations are hoisted to the top of their scope, so you can invoke them before they appear in your code.

Function Expressions

Functions can also be defined as expressions and assigned to variables. These are not hoisted in the same way.

// Anonymous function expression
const add = function(a, b) {
  return a + b;
};

// Named function expression
const subtract = function subtractNumbers(a, b) {
  return a - b;
};

console.log(add(5, 3));      // 8
console.log(subtract(10, 4)); // 6

Key Feature: Function expressions are not hoisted. You must define them before calling them.

Arrow Functions

Introduced in ES6, arrow functions offer a concise syntax and lexical this binding.

// Implicit return (single expression)
const multiply = (a, b) => a * b;

// Explicit return (block body)
const divide = (a, b) => {
  if (b === 0) {
    console.error('Division by zero');
    return null;
  }
  return a / b;
};

console.log(multiply(4, 2)); // 8
console.log(divide(10, 2));  // 5

Key Features:

  • Shorter syntax, especially for simple one-liners.
  • Inherits this from the surrounding context (lexical this).
  • No arguments object—use rest parameters (...args) instead.
  • Cannot be used as constructors (no new).

Which One to Use?

  • Declarations: Great for general-purpose functions; hoisting can be helpful but placing them at the top increases clarity.
  • Expressions: Ideal when passing functions as callbacks or managing scope; assign to const to prevent reassignment.
  • Arrow: Perfect for concise callbacks and methods needing lexical this.

Choose the style that best fits your use case and team conventions.

JavaScript gives you options. That doesn’t mean you need to flex all of them at once. Writing a one-liner arrow function that reads like a riddle won’t make your teammates admire you.

They might even start dreading your pull requests.

And honestly? Fair.


Next Up

👉 Mastering comparison operators (== vs. ===) to avoid subtle bugs.