After encountering a challenge with creating "private" instance variables in JavaScript, I stumbled upon this discussion. Prior to posing my question, I wanted to provide a thorough overview of the problem. My goal is to showcase a complete example of correctly implementing instance members and methods in JavaScript, highlighting potential pitfalls for developers who may find themselves in similar situations.
Let's consider the following JavaScript object:
var MessageBox = (function() {
function MessageBox(message) {
this.message = message;
}
MessageBox.prototype.Show = function() {
alert(this.message);
}
})();
This object, created using TypeScript, can be utilized as follows:
var msg1 = new MessageBox("Hello World");
msg1.Show(); // displays an alert with "Hello World"
var msg2 = new MessageBox("Bye World");
msg2.Show(); // displays an alert with "Bye World"
However, even with this implementation, accessing this.message
reveals that it is not truly private.
Now, let's examine another variation of the JavaScript object:
var MessageBox = (function() {
return function MessageBox(message) {
var message = message;
MessageBox.prototype.Show = function() {
alert(message);
}
}
})();
This modified version of the TypeScript-based MessageBox
object behaves similarly:
var msg1 = new MessageBox("Hello World");
msg1.Show(); // displays an alert with "Hello World"
var msg2 = new MessageBox("Bye World");
msg2.Show(); // displays an alert with "Bye World"
Here comes the twist!
var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // displays an alert with "Bye World"
msg1.Show(); // displays an alert with "Bye World" ...unexpected!
msg1.message // undefined
msg2.message // undefined
In this case, each new instance seems to overwrite the previous one's message, making access impossible while avoiding overlapping values.
Lastly, let's explore the final JavaScript object:
var MessageBox = (function() {
return function MessageBox(message) {
var message = message;
this.Show = function() {
alert(message);
}
}
}();
This updated object no longer utilizes Show()
on the prototype chain, resulting in the ability to maintain private variables without conflict:
var msg1 = new MessageBox("Hello World");
var msg2 = new MessageBox("Bye World");
msg2.Show(); // displays an alert with "Bye World"
msg1.Show(); // displays an alert with "Hello World"
msg1.message // undefined
msg2.message // undefined
To summarize, the final question: What distinguishes between:
MessageBox.prototype.Show = function() {
}
and
this.Show = function() {
}