![](/img/trans.png)
[英]Why Typescript adds .default() to class constructor in transpiled code?
[英]Why private variable in a class is treated as public in the transpiled code
我在打字稿中添加了以下课程
class Person {
private variable1;
public varibele2;
Person(){
this.variable1 = 'abc';
this.varibele2 = 'xyz';
}
public getVariable1(){
return this.variable1;
}
}
所以当我使用 tsc 编译代码时,它会生成以下代码
var Person = (function () {
function Person() {
}
Person.prototype.Person = function () {
this.variable1 = 'abc';
this.varibele2 = 'xyz';
};
Person.prototype.getVariable1 = function () {
return this.variable1;
};
return Person;
}());
由于 variable1 是私有的,因此该类的 obj 不应访问该类(这在打字稿代码中发生)。
相同的行为应该发生在转译的 es5 代码中(但不会发生)。
在上面示例的转译代码中,我正在创建 Person 的对象
var p = new Person();
console.log(p.variable1); // undefined
p.variable1 = 'abc1'; // setting value to variable 1
console.log(p.variable1); // 'abc1'
console.log(p.getVariable1()); // 'abc1'
在上面的代码中,我应该无法设置或获取 variable1 的值。
var p = new Person();
console.log(p.getVariable1()); // 'undefined'
p.variable1 = 'abc1'; // setting value to variable1
console.log(p.getVariable1()); // 'abc1'
在上面的代码中,我试图使用 p.getVariable1() 获取值,但我得到了 undefined.Since 值已经在类的构造函数中分配,它应该可以通过 p.getVariable1() 获得
var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'
在上面的代码中 Variable2 应该重新运行 'xyz' 但它不是。 一旦我为它赋值,它就会返回。
所以私有变量和公共变量的行为在转译的代码中是相同的,并且非常令人困惑。 它不返回在构造函数中分配的值。
从评论中继续我们的讨论,以下是使用 public 与 private 的好处:
IDE 会立即告诉您您正在做不应该做的事情。 如果您忽略这些错误,代码将编译为 javascript 并运行,但重点是您不要忽略这些错误。 当你写出这样糟糕的代码时,打字稿会告诉你有问题,然后你就可以解决这个问题。 如果您有一个构建过程,您可以设置它以便这些打字稿错误将使构建失败,从而迫使您在部署之前修复问题。
Typescript 是一种帮助您编写更好的 javascript 代码的工具,通过更早、更轻松地捕获错误。 它不是改变 javascript 工作方式的工具。 Typescript 不提供运行时类型检查,如果这就是您所追求的,您将找不到它。 如果你需要闭包来隐藏变量,那么你自己创建一个闭包。
首先,回答你的主要问题:
为什么类中的私有变量在转译的代码中被视为公共变量。
确实, private
属性以及readonly
属性都被转换为普通属性,因此是“公共”属性。 我认为这是为了简化和促进转译 TS→JS 并支持在任何地方使用 TypeScript,在对这些类型的属性执行无效操作时会发出警告或错误:访问类外的私有属性,重新分配只读属性......
但是你举了一些行为非常奇怪的例子。 它们不是由于 TypeScript 转译。 我注意到你的班级 Person 有一些问题导致了他们:
constructor
定义的,而不是类名。 更令人困惑的是,构造函数被转译为类似于类的函数构造函数,这里是Person
。varibele2
而不是variable2
。 这就是console.log(p.variable2)
无法打印预期值的原因。解决这些问题后,代码的行为更加合乎逻辑。
class Person {
constructor(private _variable1 = 'abc', public variable2 = 'xyz') { }
public get variable1() { return this._variable1; }
}
console.log(new Person()); // → Person { v1: [Getter], v2: "xyz", _v1: "abc", __proto__... }
转译后的代码可通过TypeScript playground 获得。
注意:我喜欢另一种语法:
_x
以方便编写 getter get x() { return this._x; }
get x() { return this._x; }
. 这也是一个常用的 JavaScript 约定,用于指示变量是私有的,没有复杂的模式来真正拥有私有属性。根据我的理解,在以下情况下,variable2 未定义,因为对象 p 不包含该变量。
在下面的代码中,我们使用 p.variable2 = 'xyz1' 将变量包含到对象 p 中。 所以在第三行我们得到了那个变量的值。
var p = new Person();
console.log(p.variable2); // undefined
p.variable2 = 'xyz1'; // setting value
console.log(p.variable2);// 'xyz1'
问题仍然是因为 typescript 已经声明了变量,那么为什么 javascript(compiled code) 对象不包含这些变量?
如果转译后的代码没有使用闭包将其设为私有,则意味着在将其用作 javascript 库时我可以无视变量,因为我永远不会知道什么是私有的,什么不是。 所以答案是转译打字稿的方式是不正确的,而不是真正的 javascript 使用精神。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.