I have two questions about ts.
uncompiled code
class K {
private p = 3;
public q = 4;
public r = () => {
console.log(this.p, this.q);
};
}
new K().r();
compiled code
var K = /** @class */ (function() {
function K() {
var _this = this;
this.p = 3;
this.q = 4;
this.r = function() {
console.log(_this.p, _this.q);
};
}
return K;
})();
new K().r();
I thought the code would be something like below to make q private. Why TS does not do it?
var K = /** @class */ (function() {
var p = 3;
function K() {
var _this = this;
this.q = 4;
this.r = function() {
console.log(p, _this.q);
};
}
return K;
})();
new K().r();
If it does not use module pattern, anonymous function seems to be useless. The code could be like below I think.
var K = function() {
var _this = this;
this.p = 3;
this.q = 4;
this.r = function() {
console.log(_this.p, _this.q);
};
};
new K().r();
Why private variables become public after compilation?
The idea of private properties directly on an instance is a very new one (using #
syntax). There is no such keyword as private
or public
in actual Javascript. Declaring a property private or public in Typescript is there to help you and others who read and use the code understand how the code is meant to be used, but it doesn't make it required.
For similar reasons, you can write
window.fn = (arg: string) => {
console.log(arg.slice(5));
};
and then, outside of the project, in Javascript, write
window.fn(5);
despite the fact that fn
only accepts a string.
If you want to make the properties actually inaccessible from the outside, use #
, eg:
class K {
#p = 3;
This syntax is extremely new in Javascript, and is only supported in Typescript 3.8+. Eg
class K {
#p = 3;
public q = 4;
public r = () => {
console.log(this.#p, this.q);
};
}
new K().r();
compiles to
"use strict";
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, privateMap) {
if (!privateMap.has(receiver)) {
throw new TypeError("attempted to get private field on non-instance");
}
return privateMap.get(receiver);
};
var _p;
var K = /** @class */ (function () {
function K() {
var _this = this;
_p.set(this, 3);
this.q = 4;
this.r = function () {
console.log(__classPrivateFieldGet(_this, _p), _this.q);
};
}
return K;
}());
_p = new WeakMap();
new K().r();
- What is the role of wrapping anonymous function?
The whole creation of the class is encapsulated in an IIFE. Sometimes, this doesn't seem to do anything, but with some types of transpiled code, it helps prevent unnecessary scope leakage. Eg
class K {
#p = 3;
static foo = 'bar'
method() {
}
}
transpiles to
"use strict";
var K = /** @class */ (function () {
function K() {
_p.set(this, 3);
}
K.prototype.method = function () {
};
var _p;
_p = new WeakMap();
K.foo = 'bar';
return K;
}());