Honest private properties in prototype
Hello!
Over the past 10 years (Happy Birthday, prototype.js!), Many libraries have been written to emulate full-fledged OOP in javascript.
All of them, one way or another, solved the problem of implementing private members of the class.
Many spears were broken and as a result, the developers were divided into 2 parts:
The first hides private properties in the scope of the constructor and refuses to use prototypes (creates methods for each instance of the object again), the second just uses the naming convention like "_privateProperty" and essentially does not encapsulate data.
Theory:
The new keyword allows you to call a function in such a way that inside it this will be equal to an empty object with prototype methods. Thus, inside the constructor, you can form an object that returns from the constructor without explicitly specifying return.
But if the function called with new explicitly returns any value other than primitive types (string, number, NaN, etc.), then this result will return, despite the fact that the same empty object and methods will be available inside the constructor through this from the prototype.
Practice:
If we assume that all this properties are private, and we return public properties explicitly, we get an elegant emulation of private properties:
For example, I wrote a simple function that “wraps” the constructor and hides private methods from the prototype:
github.com/poluyanov/privatize/blob/master/privatize.js
Pros:
Minuses:
The method does not pretend to be innovative, and perhaps you often use this approach in your work. I will be glad to your comments.
Over the past 10 years (Happy Birthday, prototype.js!), Many libraries have been written to emulate full-fledged OOP in javascript.
All of them, one way or another, solved the problem of implementing private members of the class.
Many spears were broken and as a result, the developers were divided into 2 parts:
The first hides private properties in the scope of the constructor and refuses to use prototypes (creates methods for each instance of the object again), the second just uses the naming convention like "_privateProperty" and essentially does not encapsulate data.
Theory:
The new keyword allows you to call a function in such a way that inside it this will be equal to an empty object with prototype methods. Thus, inside the constructor, you can form an object that returns from the constructor without explicitly specifying return.
var Animal = function(name){
this._privateName = name;
};
Animal.prototype.getName = function(){
return this._privateName;
};
var a = new Animal('Cow');
a._privateName === a.getName(); /* true */
But if the function called with new explicitly returns any value other than primitive types (string, number, NaN, etc.), then this result will return, despite the fact that the same empty object and methods will be available inside the constructor through this from the prototype.
Practice:
If we assume that all this properties are private, and we return public properties explicitly, we get an elegant emulation of private properties:
var Animal = function(name){
var self = this;
this._privateName = name;
return {
hello: Animal.prototype.hello.bind(this)
};
};
Animal.prototype.getName = function(){
return this._privateName;
};
Animal.prototype.hello = function(){
return 'hello ' + this.getName();
};
var a = new Animal('Cow');
a._privateName; /* undefined */
a.getName(); /* Exception */
a.hello(); /* hello Cow */
For example, I wrote a simple function that “wraps” the constructor and hides private methods from the prototype:
github.com/poluyanov/privatize/blob/master/privatize.js
Pros:
- The main plus of this approach is that on a large number of objects, working with prototypes and their methods is initially faster than the traditional creation of methods for each instance of the object: jsperf.com/scopevsprototype
- Sometimes it can be convenient to dynamically override prototype methods for a number of objects.
- Inside the prototype, you can hide (For real!) The common fields for many objects (for example, counters).
Minuses:
- Since the constructor function returns a simple object, instanceof does not work;
- This approach may seem implicit and unobvious to some.
The method does not pretend to be innovative, and perhaps you often use this approach in your work. I will be glad to your comments.