首页 > 解决方案 > TS 最终编译成 JS,JS 中不具备的功能究竟是如何实现的?

问题描述

我是在 JS 之后学习 TS 的,据说很多 JS 中没有的特性就像类型一样,都是使用 TS 实现的。但最终 TS 被编译成 JS。那么这怎么可能呢?如果后一种语言最终转换为第一种语言,如何使用另一种语言来实现一种语言中不可用的功能?

标签: javascripttypescriptcompilationtranspiler

解决方案


因此,正如评论中所述,打字稿在运行时不会做任何事情。转译后,所有类型信息都一去不复返了。打字稿的目的只是事先检查您的代码并发现潜在的错误,这可能会在执行生成的 javascript 代码时导致问题。执行检查后,它的所有不属于 javascript 的功能都将被删除。private并且public也被删除,它们存在的唯一原因是在您的代码中您不能使用它们。但这只是一个“建议”,您可以完全忽略它(因为同样,private在运行时不存在)。例如,您可以执行以下操作:

class Foo {
  private bar() {}
}
;(new Foo() as any).bar()

甚至

class Foo {
  private bar() {}
}
// @ts-ignore
new Foo().bar()

在这里,您已经成功地欺骗了 typescript 编译器,并且此代码在编译后将完全正常工作,即使该bar方法是私有的并且不应该是可访问的。

谈到“所有高级语言都具有像打字稿这样的类型系统吗?”。好吧,我不会这么说。

以 C 为例。运行时本身也不存在类型。当程序被编译、组装和执行时,一切都只是一个 1 和 0 的序列,计算机不在乎内存位置是否包含字符串或布尔值或其他任何东西,一切都只是一个位序列。但是,类型对于您的程序工作至关重要,因为类型定义了内存中有多少字节被视为单个变量。就像你定义一个整数变量一样,你让编译器知道这个变量将占用内存中的 4 个字节,例如,当向这个变量添加一个值时,它应该更新所有 4 个字节。如果您定义一个char变量,它只知道更新 1 个字节。

但是这些类型在运行时并不真正存在,您完全可以使用一些指针恶作剧来欺骗编译器,使其认为char您定义的变量实际上是一个整数。会不会造成问题?很多。酷吗?哎呀,是的。现在每次你向这个变量添加一个数字,你的程序会更新 4 个字节而不是一个,可能会擦除这 3 个字节中不属于你的变量的一些重要信息,祝你调试顺利。

与其他语言有点不同,就像 Java 抽象出这个指针诡计,所以你不能轻易欺骗编译器。但是,不同类型的变量在编译后仍然会生成不同的字节码。

因此,在某些语言(如 C 和 Java)中,类型实际上会影响程序的工作方式(如变量占用的字节数),但在 typescript 中则不会。你总是可以any对任何一段代码使用和禁用类型检查,如果算法是正确的,它仍然可以工作。但在 C 中并非如此


推荐阅读