【发布时间】:2025-11-22 11:25:01
【问题描述】:
Typescript 提供了 public,protected 和 private 关键字来定义成员的可见性或在它们旁边声明的方法,但是,我知道由于 ES6 Javascript 允许使用前缀“#”到类成员或方法以达到相同的结果。
为了更好地了解幕后的工作原理,我在 Typescript 中编写了一个玩具类,只是为了看看它是如何在 javascript 中编译的:
class aClass
{
#jsPrivate: number;
get jsPrivate()
{ return this.#jsPrivate};
private tsPrivate: number;
protected tsProtected: number;
public tsPublic: number;
constructor( a: number, b: number, c: number, d: number)
{
this.#jsPrivate = a;
this.tsPrivate = b;
this.tsProtected = c;
this.tsPublic = d;
}
}
console.log(new aClass(1,2,3,4));
使用 tsc --target es6 和 Typescript 版本 4.3.5 编译的内容变为:
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
if (kind === "m") throw new TypeError("Private method is not writable");
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
};
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
};
var _aClass_jsPrivate;
class aClass {
constructor(a, b, c, d) {
_aClass_jsPrivate.set(this, void 0);
__classPrivateFieldSet(this, _aClass_jsPrivate, a, "f");
this.tsPrivate = b;
this.tsProtected = c;
this.tsPublic = d;
}
get jsPrivate() { return __classPrivateFieldGet(this, _aClass_jsPrivate, "f"); }
;
}
_aClass_jsPrivate = new WeakMap();
console.log(new aClass(1, 2, 3, 4));
我不确定我做的是否正确,但我注意到 js 样式的私有成员现在在全局范围内,而且使用 typescript 修饰符声明的成员现在都是公共的,尽管理论上任何访问在编译为 javascript 时应该捕获私有成员,我不确定这是否是代码安全的最佳选择。
对于修改成员可见性的最佳方法,您有什么建议吗?
您能否也向我解释一下为什么会有这些差异?
【问题讨论】:
-
看起来 TS 编译器没有使用 JS
private功能。无论哪种方式,使用你喜欢使用的东西。如果您在 TS 中编程,这并没有什么不同,因为编译器会处理可见性/访问问题。 -
"因为 ES6 Javascript 允许对类成员或方法使用前缀“#”以达到相同的结果。" 1. 不是 ES6,这个是一个最近的变化,还没有正式发布。 2. 仅供private访问,没有“受保护”访问级别。
标签: javascript typescript visibility member access-modifiers