I'm new to JavaScript and I'm trying to wrap my head around creating "classes" with private data and public functions. I've been told Immediately Invoked Function Expressions (IIFE) accomplish this but when I "instantiate" new objects from the class they reference the private data instead of holding their own.
Some of this is borrowed from Create a JS class: IIFE vs return prototype
For example, a simple Car "class":
var Car = (function() {
var body = { color: 'red' };
Car.prototype.newColor = function(color) {
body.color = color;
};
Car.prototype.getColor = function() {
return body.color;
};
return Car;
})();
var car1 = new Car();
var car2 = new Car();
car2's color also gets changed to purple.
car1.newColor('purple');
car2.getColor(); // 'purple'
I want each object of the Car class to hold its own private data. How can this be accomplished with IFFE, or is there another way?
But that way you define
.privilegedMethod()
each time an object is created and each of them will hold diferent version of the ( same purpose ) method...Solution I came up with is to use object to object ( private ) hashmap, and map the newly created object to it's corresponding data in ctor function, and use hasmap as 'manager' to figure out which data correspond to which object, in prototype methods, something like this:
The only way to simulate private instance variables it to declare them as
var myprivate
in the constructor function.Any privileged method (=method that can access the private member) has to be declared within the constructor function's body as well so can't be on the prototype (will cost you extra cpu and memory and maybe doesn't optimize as well in some JS engines).
I never had a situation where it was needed to do this since in my opinion the cost is not worth the gain. Usually indicate to my future self and other programmers that a member is private by a widely used naming convention (name starts with underscore)
_myPrivate
"Public override"'s answer inspired me to create the following code. Private instance members can be accessed publicly by
ben._data.set
or you could re implement rules and or getters/setters so someone could still abuse it. It can still clean up you're object's publicly accessible members and making it easier to use the getters and setters.Note of caution:
Person.rules
needs to be copied to Child instances when you want to inherit from Person.More about prototype, inheritance, overriding, calling super, multiple inheritance(mix in) and the value of
this
here: https://stackoverflow.com/a/16063711/1641941