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
- Why does the TypeScript compiler ignore access modifiers when compiling to JavaScript?
- Why does TypeScript bind all methods to the prototype, rather than on a per-instance basis?
- If there is anything favorable about the way TypeScript compiles classes in comparison to my custom implementation, what is it, and why?