1

As we know, you can make a "Class" variable "private" in JavaScript by doing the following:

function ClassName(attribute){
    var privateAttribute = attribute;

    this.accessor = function(){
        return privateAttribute;
    }

    this.mutator = function(x){
        privateAttribute = x;
    }
}

I know that this works, and I've used it before. But it kind of breaks down my understanding a tad. Aren't local variables supposed to go out of scope at the end of a function's execution? Shouldn't, according to how JavaScript scope is supposed to work, var privateAttribute be inaccessible by the time you try to call accessor from an instance of ClassName?

https://www.w3schools.com/js/js_scope.asp

3
  • 1
    It remains in scope to members of the object as long as it exists. I'm certain someone will come along with a detailed technical explanation of why that is that I can't articulate right at the moment, but you can be confident that that behavior is well-defined and will remain consistent. Commented Jun 15, 2017 at 20:57
  • 1
    stackoverflow.com/q/500431/215552 Give it a read. Commented Jun 15, 2017 at 20:58
  • Possible duplicate of What is the scope of variables in JavaScript? Commented Jun 15, 2017 at 21:28

1 Answer 1

2

What you are missing is that fact that a function can be called in several ways...

If your function is called as a function, then, yes, when the function ends, all its local data is gone.

But, if the function is called as a "constructor function":

var myObj = new ClassName(data);

Then the function creates an instance of an object, which is stored in the myObj object variable and all the function's private data is available (internally of course) until the object variable goes out of scope.

In addition to this, if a function contains a "closure" (a nested scope that refers to a variable from a higher scope) and that nested function winds up having a longer lifetime than the higher scope where the higher variable came from, then that variable cannot go out of scope even when the function it was defined in does. This concept trips a lot of people up at first, but it makes perfect sense - if a (let's say) returned function relies on data that would normally go out of scope when its block terminates, but the returned function lives longer than this, then the data will not and cannot be garbage collected.

Lastly, and really just to be clear, JavaScript does not actually have classes. It has prototypes and it is these prototypes that an object will inherit from. Because of how prototypes and inheritance work in JavaScript, your example code would really be written with methods being attached to the prototype, so that all instances of the object (created via a constructor function invocation) don't have to store the same function (thus, decreasing the memory footprint of those instances).

function ClassName(attribute){
    // A regular variable will act as a private "class field"
    var privateAttribute = attribute;

    // But members that are attached to 'this' become instance fields
    this.exposedPrivateData = privateAttribute;
}

// Methods get attached to the underlying prototype object that
// all instances of your object will inherit from
ClassName.prototype.accessor = function(){
        return this.exposedPrivateData;
};

ClassName.mutator = function(x){
        this.exposedPrivateData = x;
}
Sign up to request clarification or add additional context in comments.

1 Comment

@user3496058 Actually, its not messed up at all, but it takes a little getting used to because JavaScript is not like most other languages. JavaScript has "lexical scope" and once you get your head around that, a lot of things become clear.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.