JavaScript无疑是当今最火爆的编程语言之一,它的崛起要归功于AJAX、Node.js的出现以及时下各种MVC框架的流行。但作为一门在十天之内创建出来的语言,JS本身存在着一些不完善之处、以及容易令人疑惑的地方,例如不支持强类型以及new关键字的用法。尤其与当前主流的面向对象语言以及动态语言相比,其不足之处显得尤为突出。
为了克服JS语言中的缺陷,让更多的人能够编写出优秀的代码,市面上出现了大量能够将其它编程语言转译为JS的工具。其中较知名的有CoffeeScript、Dart、GWT、Script#,以及本文的主角TypeScript与Haxe。
TypeScript是这一领域中的新贵,由微软于2012年发布。近期发布到1.5版,加入了大量ES6的特性。TypeScript被设计为JS的一个超集,因此现有的JS都是合法的TypeScript代码。这门语言也得到了Angular团队以及Telerik的支持。
作为这一领域中的老前辈,Haxe从2006年起就提供了转译为JS的功能。与TypeScript类似,Haxe也提供了一套类似于JS的语法、静态类型系统以及模块。除了JS之外,Haxe还能够提供编译为Flash、PHP、C++等语言的功能。
来自Haxe的员工Andy Li最近在博客中对TypeScript与Haxe进行了一次全面的比较,包括语法、底层语义、类型系统、以及组织和生成代码的方式。为开发者如何在这两种工具间进行选择提供了一个不错的参考。
语法
TypeScript与Haxe的基础语法是非常相似的,它们都支持在定义变量时声明类型。但Haxe在设计时引入了函数式编程的概念,因此Haxe中的大部分语法元素其实都是一种表达式,可以代表某个值。
// It is evaluated as the last expression inside it. // Here is an example that use try-catch expression together with block expressions. var result = try { var a = computationThatMayThrow(); finalComputation(a); } catch (exception:Dynamic) { rollBack(); defaultValue(); }
另一个不同点表现在两者处理分号的不同。TypeScript会自动在行末添加分号,因此不强制开发者使用分号。但这在Andy看来是一种极端错误的做法,它可能会带来意料之外的后果。而Haxe强制要求开发者在行末使用分号。
其它的一些语法差别还包括:
Andy认为总的来说,两者的语法具有高度的相似性,TypeScript本身提供了许多用以简化代码的语法,而Haxe则可通过宏进行扩展,使特定表达式的语义产生转变。
语义
虽说TypeScript与Haxe在语法上非常近似,但它们在语义方面有着相当大的差距。首先两者对于变量的范围有着完全不同的定义,TypeScript的变量范围与JS相同,通过var定义的变量作用于整个函数,而Haxe的变量范围与现代语言更为接近,变量的范围作用于一个代码块。
// TypeScript { var a = 1; } console.log(a); // ok, because `a` exist outside of a block // Haxe { var a = 1; } trace(a); // error: Unknown identifier : a
在Andy看来,块范围的做法更适合于块结构的语言。实际上,JavaScript的作者Brendan Eich也承认,当初选择以函数作为变量范围的做法是因为时间紧迫。
其它一些语义方面的差别还包括:
Andy总结道,TypeScript选择尽可能遵循JS标准的语义,因此如今的JS开发者能够很容易上手。而Haxe的做法是尽可能修复JS的设计缺陷,遵循当今主流语言的设计方式,因此对于不具备JS开发经验的用户更具吸引力,并且Haxe中引入了部分函数式编程的概念,它很好地与类似于JS的语法相容。
类型系统
TypeScript与Haxe的基本类型非常接近,后者只是多了一个Int类型。两者都支持自定义类型,TypeScript中可以使用类/接口及枚举,而Haxe中还多了typedef与abstract两个选择。
以下是Andy对两者的类型系统进行的一些具体比较:
Andy总结说,Haxe的类型系统比TypeScript更为严格,但后者有时能够简化我们的工作。不过在他看来,如果出现了明显的类型问题,应当中止编译过程。Andy认为这种宽容会造成开发者的滥用,这方面的一个例子就是IE,它对语法错误的宽容让开发者逐渐地忽视了语法错误与Web标准。而TypeScript很不幸地继承了微软的这一传统……
代码组织与生成
TypeScript的代码组织方式与JS一样灵活,在一个.ts文件中可以包含语句、函数与类的定义,还可以使用三种模块系统,可以导出变量、函数与类型。
Haxe的代码组织方式更像静态语言,不允许在顶层出现表达式(包括函数),只能包含在类型(主要是类)中。Haxe程序的入口方法是某个用户指定类中的静态main函数。
在文件组织上,TypeScript可以将.ts文件放置在任意位置上。而Haxe的做法类似于Java,其文件结构必须对应于包与模块的层次。
在代码生成时,Haxe能够进行较多的高级优化功能,例如删除不可访问的代码,对函数进行内联等等。而TypeScript中的优化功能比较单一,主要是将一些高级语法特性转译为ES3/5所支持的JS语法。
Andy在总结中表示,从代码的组织与生成来说,TypeScript表现出较高的灵活性,更接近于JS。而Haxe借鉴了主流编译型语言的经验,对于文件目录要求较严格。
结论
在文章的最后,Andy对他的观点进行了一番总结。他认为这两门语言具有一定的相似性,但在设计思想上有许多不同之处。TypeScript总体更接近原生的JS,对于JS开发者来说更容易上手。而非JS开发者或许会喜欢Haxe,它更接近于现代的静态语言,同时引入了许多函数式编程的概念,进一步加强了它的语法特性。
Andy个人更偏向于使用Haxe,除了因为他本身就是Haxe Foundation的一员之外,还因为Haxe能够提供编译为其它语言的功能,而这一点是TypeScript所不具备的,因为后者设计时就是为了编译为JS这个目的而生。
感谢魏星对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至[email protected]。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流(欢迎加入InfoQ读者交流群)。