Are there really no private variables in JavaScript?

Private variables are variables that are visible only to the class to which they belong. It is a common opinion that there are no strict private variables in JS (except for the new fields like this.#property).
Can anyone kindly explain why the variable ‘boy’ bellow cannot be considered to be a private one?

class Forrest {
  constructor() {
    let boy = "Bobby"
    this.getBoy = function() {
      console.log(boy)
    }
  }
}

const f = new Forrest()
f.getBoy() // Bobby

41 thoughts on “Are there really no private variables in JavaScript?”

  1. I haven’t heard people claim that boy in your example isn’t private. Quite the opposite, it’s private to the constructor and getBoy. Nothing else (including nothing else in that class) can access it. But either way, I suppose that might be in the "opinion-based" realm.

    Stepping out of that realm: Regardless of someone may feel about the closure approach shown in the question, JavaScript will have true private fields very, very soon. It’s implemented in most major engines and likely to hit the spec this year. Your example with private fields looks like this:

    class Forrest {
        #boy = "Bobby";
    
        getBoy() {
            console.log(this.#boy);
        }
    }
    
    const f = new Forrest();
    f.getBoy() // Bobby

    Or if we set it from a constructor parameter:

    class Forrest {
        #boy;
        constructor(boy) {
            this.#boy = boy;
        }
    
        getBoy() {
            console.log(this.#boy);
        }
    }
    
    const f = new Forrest("Bobby");
    f.getBoy() // Bobby

    Those will run on up-to-date versions of Chromium-based browsers. Safari and Firefox won’t be much longer.

    Reply
  2. This is the concept of closures in JS.

    Closure means that an inner function always has access to the vars and parameters of its outer function, even after the outer function has returned.

    So in this example, f.getBoy (the inner function) has access to boy property (parameters of it’s outer function) but if you will try to access
    f.boy you will get undefined.

    Closure can be very useful in hiding implementation detail in JavaScript.
    it can be very useful to create private variables (or functions).

    class Forrest {
      constructor() {
        let boy = "Bobby"
        this.getBoy = function() {
           console.log(boy)
        }
      }
    }
    
    const f = new Forrest()
    f.getBoy() // Bobby
    f.boy // undefined
    
    Reply

Leave a Comment