I can use immediate invocation to create an object with methods that have access to private members.
var myObj = (function () {
// Private member variables
var privateX;
function setPropX (value) {
privateX = value;
}
function getPropX () {
return privateX;
}
function init() {
privateX = "Initial value privateX";
}
init();
// Public API
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX
};
}());
After this I can work with the object just fine using the public API but my private members are correctly hidden:
myObj.setPropX("Hello world");
alert(myObj.getPropX()); // --> Hello world
alert(myObj.privateX); // --> Undefined
Now for my question:
Is it possible to add public properties to the object which can be accessed both by the caller and from within my code? They would then be used like this:
myObj.publicY = "ABC";
myObj.sayPublicY(); // Should alert --> ABC
I tried to do it like this:
var myObj = (function () {
// Private member variables
var self = this;
var privateX;
function setPropX (value) {
privateX = value;
}
function getPropX () {
return privateX;
}
function sayPublicY () {
alert(self.publicY);
}
function init() {
privateX = "Initial value privateX";
self.publicY = "Initial value publicY";
}
init();
// Public API
return {
// Methods
"setPropX": setPropX,
"getPropX": getPropX,
"sayPublicY": sayPublicY
};
}());
I thought this would work but it doesn’t. The selfreference saved in the closure is referencing the window object. Why does it not reference myObj ?
I must be missing something obvious but I couldn’t find anything on Google or SO.
What is the correct way to do this?
EDIT: Added details of init() method which is still not working
Because inside your closure
this(var self = this;) equals thewindowrather than the instance you’ve created. This declaration ofselfis useless; as it’ll always equalwindow, and should be removed (and not used).The resolution of
thisis delayed until execution time, however because you’re specifically usingselfinstead ofthis, you’re always usingwindow. ChangeselftothisinsidesayPublicY, and it’ll work.The use of an
initfunction using this form of construction is not valid. Theconstructorin this code is the following few lines:Up until those few lines, you do not have an instance of
myObj. You merely have the definitions and declarations of private variables/ methods which could be added to themyObjobject. The return statement constructs yourmyObj, and assigns it the methosdsetPropX,getPropXandsayPublicY. This is also where you should add yourpublicYattribute: