Before I proceed, I would like to point out that I have asked a few questions already regarding TypeScript, its compiler and what it has and has not been able to achieve throughout its life and roadmap towards version 1.0
This question relates to the use of public
and private
keywords in TypeScript, and how these relate to compiled JavaScript.
Consider the following TypeScript class:
class Example {
private messageA: string;
public messageB: string;
constructor(message?: string) {
this.messageA = "private: " + message;
this.messageB = "public: " + message;
}
public showMessageA(): void {
alert(this.messageA);
}
private showMessageB(): void {
alert(this.messageB);
}
}
var example = new Example("Hello World");
Now, when I type example
. intellisense (TypeScript) tells me that I can access messageB
, and showMessageA
, because they are both public
. However, this behavior (whilst possible) is not evident in the compiled JavaScript.
Here is the JavaScript compilation for my class:
var Example = (function () {
function Example(message) {
this.messageA = "private: " + message;
this.messageB = "public: " + message;
}
Example.prototype.showMessageA = function () {
alert(this.messageA);
};
Example.prototype.showMessageB = function () {
alert(this.messageB);
};
return Example;
})();
var example = new Example("Hello World");
Now, if I paste this example into my browser console (I'm using Chrome), I can access messageA
, messageB
, showMessageA
, showMessageB
which implies that in JavaScript, all access modifiers are ignored.
Personally, I think this is wrong! JavaScript is capable of modelling access modifiers so it is my belief that TypeScript should follow suit.
Consider the following hand written JavaScript, which models the private
and public
variables and functions correctly:
var Example = (function() {
return function Example(message) {
var messageA = "private: " + message;
this.messageB = "public: " + message;
this.showMessageA = function() {
alert(messageA);
}
var showMessageB = function() {
alert(this.messageB);
}
}
})();
var example = new Example("Hello World");
Now, if I paste this example into my browser console, I can only access messageB
and showMessageA
, which in accordance with what I was trying to achieve with TypeScript is correct.
QUESTIONS
The problem with using a closure to imitate private access is that every instance needs its own copy of each method. This means that every time you create an instance, each method function has to be compiled and space in memory has to be reserved for the new function. That is not ideal, and not what TypeScript is trying to achieve.