Some are saying that JavaScript does not have private properties with prototypes and it is not like TypeScript or Python.
However, that is not fully correct, especially with this comparison.
Python doesn't have anything private. All the scopes are globally addressable and all the variables, properties and methods are accessible globally (as long as you know the scope path, which could be easily traced from within the software itself).
TypeScript is just a pre-processor. It will do extra semantic checks during compilation, but no enforcement of anything on runtime.
However, it is generally untrue that you have no private properties available in JavaScript.
You do have scope inheritance and you don't have global access to any scope from outside. Therefore you can make private properties easily.
For example, if you have:
function F1() {
var XXX = 0;
return function () {
return XXX;
}
}
F1()() will respond with the value of XXX but there is no way to access XXX from outside.
So what about prototyping?
You can do this there too.
You can do this there too.
function F1() {
var XXX = 'yyy'; // Private property
function F1() {
// You constructor is here
this.YYY = 'xxx'; // public property
}
F1.prototype.method1 = function() {
return XXX + this.YYY;
}
return new F1();
}
Then if you do:
x = F1();
or
x = new F1(); // Both works the same way
and check:
console.log(x.YYY); // output 'xxx'
console.log(x.XXX); // output Error
console.log(x.method1()); // output 'yyyxxx'
So everything works! You have prototyping with private and public properties.
The same way you can do private and public methods.
The only thing that will not work with this method is instanceof
x instanceof F1 will respond with false, because x is not an instance of the upper F1, but the inner F1
The current ES6 standard have classes, but they are essentially a wrapper on top of prototype. So this technique still apply. Additionally with Object.defineProperty you could apply extra protection on top of a property.
There is another approach to the problem. Without prototypes.
function F1() {
if (!this instanceof F1) return; // Protect against global scope polution
var XXX = 'yyy'; // Private property
this.YYY = 'xxx'; // Public property
function PrivateMethod() {
return XXX + this.YYY;
}
this.method1 = function() {
return PrivateMethod();
}
}
The current ES6 standard have classes, but they are essentially a wrapper on top of prototype. So this technique still apply. Additionally with Object.defineProperty you could apply extra protection on top of a property.
There is another approach to the problem. Without prototypes.
function F1() {
if (!this instanceof F1) return; // Protect against global scope polution
var XXX = 'yyy'; // Private property
this.YYY = 'xxx'; // Public property
function PrivateMethod() {
return XXX + this.YYY;
}
this.method1 = function() {
return PrivateMethod();
}
}
With the shown above approach you have both private and public methods and properties, with workable instanceof