关于ts我有两个问题。
未编译的代码
class K {
private p = 3;
public q = 4;
public r = () => {
console.log(this.p, this.q);
};
}
new K().r();
已编译的代码
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();
我以为下面的代码将q设为私有。为什么TS不这样做?
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();
如果不使用模块模式,则匿名函数似乎无用。我可能认为代码如下。
var K = function() {
var _this = this;
this.p = 3;
this.q = 4;
this.r = function() {
console.log(_this.p, _this.q);
};
};
new K().r();
答案 0 :(得分:1)
为什么私有变量在编译后成为公共变量?
在实例上直接 私有属性的想法是一个非常新的想法(使用#
语法)。实际的Javascript中没有private
或public
这样的关键字。可以在Typescript中声明私有或公共属性,以帮助您和其他阅读和使用该代码的人了解该代码的使用意图,但并不能使其成为必需< / em>。
出于类似的原因,您可以写
window.fn = (arg: string) => {
console.log(arg.slice(5));
};
然后在项目外部用Javascript编写
window.fn(5);
尽管fn
仅接受字符串。
如果要使属性实际上无法从外部访问,请使用#
,例如:
class K {
#p = 3;
此语法在Javascript中是一个非常新的,并且仅在Typescript 3.8+中受支持。例如
class K {
#p = 3;
public q = 4;
public r = () => {
console.log(this.#p, this.q);
};
}
new K().r();
编译为
"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();
- 包装匿名函数的作用是什么?
整个类的创建都封装在IIFE中。有时,这似乎无能为力,但是对于某些类型的已编译代码,它有助于防止不必要的作用域泄漏。例如
class K {
#p = 3;
static foo = 'bar'
method() {
}
}
转换为
"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;
}());