Leaderboard
Javascript Jul 6, 2026
Javascript Iife Module Pattern Private State

JavaScript Closures — What Does This Output?

This is a daily Javascript challenge from the CodeShot archive. Practice your knowledge of Iife Module Pattern Private State and improve your technical interview readiness.

const fn = (function() {
  let x = 0
  return {
    increment() { x++ },
    getValue() { return x }
  }
})()
fn.increment()
fn.increment()
console.log(fn.getValue())
A 0
B 1
C 2
D undefined

Detailed Explanation

Why This Question Matters

If you've spent any time in a JavaScript interview, you've probably run into a question like this. On the surface, it looks like basic arithmetic. But in reality, it's a test of whether you actually understand closures and the Module Pattern.

Many developers struggle with this because they think about scope as a static thing. They assume that once a function finishes executing, everything inside it vanishes. In JavaScript, that's not how it works. Understanding how functions "remember" their environment is the difference between writing buggy code and writing professional, scalable architecture.

Understanding the Code

Let's look at the snippet:

const fn = (function() {
  let x = 0
  return {
    increment() { x++ },
    getValue() { return x }
  }
})()

First, notice the parentheses at the end: })(). This is an IIFE (Immediately Invoked Function Expression). We aren't just defining a function; we are executing it the moment it's created.

Inside this IIFE, we declare let x = 0. Then, we return an object containing two methods: increment and getValue.

Here is the magic: the IIFE finishes executing and "returns" that object to the constant fn. Normally, you'd expect the local variable x to be garbage collected because the function is done. However, because the returned object contains methods that reference x, JavaScript keeps x alive in a "closure."

Essentially, x is now a private variable. It’s trapped in a bubble that only increment() and getValue() can access. You cannot call fn.x from the outside—it would return undefined.

Finding the Correct Answer

Now let's trace the execution:

1. fn.increment() is called. The closure looks at x (which is 0), increments it, and now x is 1.
2. fn.increment() is called again. x becomes 2.
3. console.log(fn.getValue()) is called. It returns the current value of x.

The output is 2. (Option C).

If you thought the answer was 0 or undefined, you likely assumed that x was reset every time a method was called, or that x disappeared after the IIFE ran. Neither is true. The state is preserved across calls because the methods share the same lexical environment.

Common Mistakes Developers Make

The most common trip-up is confusing local scope with closure scope.

Beginners often think that since x is defined inside a function, it's "temporary." They forget that if a nested function (or a method in a returned object) references that variable, the variable persists.

Another mistake is forgetting how the IIFE works. If the code had been:
const fn = function() { ... } (without the trailing ()), then fn would be the function itself, not the object. Calling fn.increment() would throw a TypeError because fn would be a function, and functions don't have an increment method unless you explicitly attach one.

Finally, some people confuse this with this. In this specific snippet, we aren't using this.x; we are using x directly from the outer scope. If the code used this.x, the result would be totally different (and likely NaN since this.x would be undefined).

Real-World Usage

You might be wondering, "Why would I ever write code like this?"

In the modern era of ES Modules, we have export and import to handle privacy. But before that, the Module Pattern was the gold standard for creating private state in JavaScript.

You still see this pattern everywhere in production:

1. State Management: If you're building a small store or a counter utility without a heavy framework, this is how you prevent external code from accidentally messing with your internal state.
2. API Clients: You can create a singleton that holds an auth token privately and only exposes methods to fetch data using that token.
3. Library Design: Many older JS libraries use this to hide "helper" functions from the global window object, preventing naming collisions.

Basically, any time you want to say, "I want this variable to be accessible to these three functions, but absolutely nobody else," you're using a closure.

Key Takeaways

  • IIFEs execute immediately and are often used to create a private scope.
  • Closures allow functions to "remember" variables from their parent scope even after the parent function has finished executing.
  • Private State is achieved by returning an object that references variables declared outside of that object.
  • State Persistence: Because the methods in fn share the same closure, they all manipulate the same x.
  • Why this matters

    Understanding Iife Module Pattern Private State is crucial for passing technical interviews. In real-world applications, this concept often leads to subtle bugs if not handled correctly. For more details, you can always refer to the official MDN Documentation.

    📝
    Reviewed by CodeShot Editorial
    Every challenge is code-reviewed by senior developers to ensure accuracy and real-world relevance. Learn more.

    Ready for your shot?

    Join thousands of developers solving one logic puzzle every morning.

    Solve Today's Challenge →