Is there any way to make “private” variables (those defined in the constructor), available to prototype-defined methods?
TestClass = function(){
var privateField = "hello";
this.nonProtoHello = function(){alert(privateField)};
};
TestClass.prototype.prototypeHello = function(){alert(privateField)};
This works:
t.nonProtoHello()
But this doesn’t:
t.prototypeHello()
I’m used to defining my methods inside the constructor, but am moving away from that for a couple reasons.
Yes, it's possible. PPF design pattern just solves this.
PPF stands for Private Prototype Functions. Basic PPF solves these issues:
For the first, just:
It's that simple. For example:
...
Read the full story here:
PPF Design Pattern
You can actually achieve this by using Accessor Verification:
This example comes from my post about Prototypal Functions & Private Data and is explained in more detail there.
You can use a prototype assignment within the constructor definition.
The variable will be visible to the prototype added method but all the instances of the functions will access the same SHARED variable.
I hope this can be usefull.
Update: With ES6, there is a better way:
Long story short, you can use the new
Symbol
to create private fields.Here's a great description: https://curiosity-driven.org/private-properties-in-javascript
Example:
For all modern browsers with ES5:
You can use just Closures
The simplest way to construct objects is to avoid prototypal inheritance altogether. Just define the private variables and public functions within the closure, and all public methods will have private access to the variables.
Or you can use just Prototypes
In JavaScript, prototypal inheritance is primarily an optimization. It allows multiple instances to share prototype methods, rather than each instance having its own methods.
The drawback is that
this
is the only thing that's different each time a prototypal function is called.Therefore, any private fields must be accessible through
this
, which means they're going to be public. So we just stick to naming conventions for_private
fields.Don't bother mixing Closures with Prototypes
I think you shouldn't mix closure variables with prototype methods. You should use one or the other.
When you use a closure to access a private variable, prototype methods cannot access the variable. So, you have to expose the closure onto
this
, which means that you're exposing it publicly one way or another. There's very little to gain with this approach.Which do I choose?
For really simple objects, just use a plain object with closures.
If you need prototypal inheritance -- for inheritance, performance, etc. -- then stick with the "_private" naming convention, and don't bother with closures.
I don't understand why JS developers try SO hard to make fields truly private.
I'm late to the party, but I think I can contribute. Here, check this out:
I call this method accessor pattern. The essential idea is that we have a closure, a key inside the closure, and we create a private object (in the constructor) that can only be accessed if you have the key.
If you are interested, you can read more about this in my article. Using this method, you can create per object properties that cannot be accessed outside of the closure. Therefore, you can use them in constructor or prototype, but not anywhere else. I haven't seen this method used anywhere, but I think it's really powerful.