04 / 18

What is the difference between a function declaration and a function expression?

A function declaration is created using the `function` keyword and is hoisted to the top of its scope.
A function expression, on the other hand, involves defining a function as part of an expression. Here's an example of a function expression:
  1. 1

    Hoisting function expression depends on the variable used to store it

  2. 2

    if its a var it will be hoisted and initialised with undefined

  3. 3

    if its let or const it will be hoisted but suffer from TDZ

Difficulty: 4/10
Topics: hoisting, lexical scope, execution context

Scenario Questions

0-2 years experience
  1. 1

    We have a utility file where we call a helper function at the top of the file, but the actual function is defined at the bottom. It works fine. But when we refactored it to a const arrow function, the app suddenly crashed with a ReferenceError. Why did this happen, and how would you fix it?

  2. 2

    Imagine you are writing a helper function inside a React component file. You want to decide whether to write 'function processItem(item) {}' or 'const processItem = (item) => {}'. How does your choice affect where you can place that helper relative to where it is called?

2-5 years experience
  1. 1

    We're debugging a legacy codebase where a function is conditionally defined inside an 'if' block using a standard 'function myFunc() {}' declaration. In some browsers, it's available outside the block, and in others, it throws an error. Why is this behavior inconsistent, and how would you refactor this to be safe and predictable?

  2. 2

    You are building a React component and need to pass a callback to a child. You're debating between declaring a helper function outside the component using 'function helper() {}' versus defining an arrow function expression inside the component body. What are the implications for memory, re-renders, and access to component state?

5-8 years experience
  1. 1

    We are designing a large-scale utility library that will be tree-shaken by Webpack or Rollup. How does choosing function declarations versus exporting const arrow function expressions affect the bundler's ability to perform dead-code elimination and scope hoisting?

  2. 2

    In a Node.js microservice, we are dynamically loading plugins at runtime. Some plugins rely on overriding core framework methods. How does the distinction between function declarations and expressions affect our ability to safely monkey-patch or decorate these methods at runtime without breaking lexical scope?

8+ years experience
  1. 1

    We are migrating a massive, 10-year-old legacy codebase from ES5 to modern TypeScript. We have thousands of implicit global function declarations and complex hoisting patterns. What architectural guidelines or automated AST codemods would you design to safely transition these to block-scoped expressions without breaking runtime execution order?

  2. 2

    When designing an enterprise-grade SDK that needs to run in highly constrained environments like Cloudflare Workers, how do you establish team-wide standards around function definition styles to optimize for engine-level optimization, such as V8's Ignition/Turbofan pipeline, and bundle size?

Follow-up Questions

  • How does the Temporal Dead Zone (TDZ) affect let/const function expressions compared to var-based expressions?
  • What happens to the 'this' context when you refactor a standard function declaration into an arrow function expression inside an object method?
  • How do modern JS engines handle block-scoped function declarations inside an 'if' statement?