TypeScript:更好的JavaScript_第1页
TypeScript:更好的JavaScript_第2页
TypeScript:更好的JavaScript_第3页
TypeScript:更好的JavaScript_第4页
TypeScript:更好的JavaScript_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、TypeScript:更好的JavaScript目录作为编程语言的TypeScript2TypeScript特性简介2对象模型的扩展3声明语义学3数据语义学3函数语义学4class和继承语义学6代码组织和重构8小结8标签:TypeScript,编程语言,JavaScrip作为编程语言的TypeScript关于TypeScript,首先要认识的一点就是:它是Anders Hejlsberg的作品。Anders是第一流的编程语言设计师,也是第一流的编译器实现者。作为Object Pascal和C#之父,Anders这次仍然采用了此前的做法:他设计了一种新的语言,并实现了这种语言的编译器,来改进一种

2、已有的语言。但这次又和此前有所不同,此前无论是Object Pascal还是C#,编译的目标代码都是机器码,而TypeScript的目标代码则是JavaScript。当然,如果把浏览器看作是虚拟机,而JavaScript看作是在这种虚拟机上运行的目标代码也无不可。总而言之,使用TypeScript这种语言撰写的源代码需要经过TypeScript编译器的编译,而产生的目标代码是标准的JavaScript。但这还不是TypeScript在语言设计层面上的特别之处,特别之处有两点。TypeScript支持on-the-fly编译,即写一句TypeScript就可以立即得到对应的JavaScript代

3、码,这个特性和CoffeeScript类似。但它比CoffeeScript支持更强的上下文推导,不需要完整的语句写完,就可以生成对应的、不完整的JavaScript代码。TypeScript是JavaScript的超集(superset),“任何合法的JavaScript都是合法的TypeScript。”这种设计很明显是借鉴了C+对于C做扩充时采用的做法,它兼容已有的JavaScript代码的决定给很多JavaScript程序员向TypeScript转型时铺就坚实的第一步他们可以从自己已有的代码出发,通过一点一点的改动来体会到TypeScript带来的好处,同时,时刻保留说“这样就够了”,然后

4、停止的权利。直到掌握了比较全面的TypeScript技术以后,才从一开始就采用TypeScript来撰写代码,而只取用编译结果。实际上,“任何合法的JavaScript都是合法的TypeScript”这种说法并不准确,准确的说法是“任何合法的ECMAScript 6都是合法的TypeScript”。当然,ECMAScript 6还是一个正在修订的语言规范,而TypeScript在现阶段生成的任何目标代码,涉及可能会引起ECMAScript 6的新特性的,都采用了向下兼容的ECMAScript 5规范作为准则。但对于各个浏览器自行对JavaScript做的那部分扩充,TypeScript不保证予

5、以支持。TypeScript特性简介前面已说过,TypeScript的设计目标是作为JavaScript或者说ECMAScript 6的超集。换句话说,如同C+的初始目标是作为“更好的C”一样,TypeScript也可以看作是“更好的JavaScript”,那么好在哪里呢?其实用C+和C的关系来做类比,还是很恰当的。TypeScript充分利用了JavaScript原有的对象模型并在此基础上做了扩充,添加了较为严格的类型检查机制,添加了模块支持和API导出的能力。比起JavaScript,TypeScript提供了更多在语言层面上的支持,使得程序员能够以更加标准化的语法来表达语义上的约束,从而

6、降低了程序出错的机率;TypeScript也使得代码组织和复用变得更加有序,使得开发大型Web应用有了一套标准方法。对象模型的扩展JavaScript支持极为广泛的对象模型,除了null和undefined以外,几乎所有的其他实体都可以视为对象,即使是数值、字符串和布尔型亦可以隐式使用其对应的包装器而直接作为对象用于一般场合。函数和数组这样在其他的编程语言中不被视为对象的实体,在JavaScript亦视为“一等对象”(first-class object),除了利用实体本身的场合,例如使用数值索引或调用函数体以外,还可以作为普通的对象拿来添加属性和方法。JavaScript对象支持在任意时刻动

7、态添加属性和方法,并且支持修改和扩充内建对象。一句话,JavaScript提供了大量进行对象操作的基础设施(facilities)和基本工具(utilities),正是这些内容构成了JavaScript丰富而灵活的对象模型。TypeScript主要从两个方面对JavaScript对象模型进行扩展:一是在核心语言方面,二是在类概念的模塑方面。声明语义学在TypeScript中书写涉及DOM对象的JavaScript代码,一般来说不会遇到问题。但这并不是因为TypeScript语言中对DOM对象有所“了解”,而是因为TypeScript默认会加载名为lib.d.ts的声明文件,其中默认已包含了所有

8、的DOM对象的声明。换言之,当你写下这个语句:之时,编译器实际上已隐式地在最前面加上了一句:这种声明称为环境声明(ambient declaration),遇到环境声明以后,TypeScript便会试图从声明的来源(如声明库中)分析和推导对象的类型信息。如果找不到任何的来源,它便默认该对象的类型为any。但无论如何,环境声明都不会向生成的JavaScript里加任何语句。事实上,所有的TypeScript声明都不会生成对应的JavaScript语句,因为JavaScript对象模型中的声明是可选的。这里也可以看出TypeScript遵循“除非必要,不生成多余的语句”的哲学。但声明在TypeSc

9、ript中除了有着预先提供类型信息的重要作用之外,编译器还能根据这些信息完成强大的类型推导,以及精准的静态类型检查。数据语义学TypeScript中的数据要求带有明确的类型,如果设定为一种类型,却要将该类型内不合法的值赋给它,则静态类型检查机制会将这样的语句标示为错误。可以采用interface关键字定义具名结构类型,这个特性类似于在JavaScript中采用字面量来定义JavaScript对象。所不同的是,在TypeScript中每个组分都必须指定类型,不过组分可以是可选的,在实际提供字面量对象时,可选组分可以不提供。同样地,interface的数据类型定义,以及在TypeScript中为数

10、据指定的任何静态类型声明,都不会在生成任何的JavaScript目标代码有任何体现。例如上面这段代码生成的JavaScript目标代码仅仅是:函数对象的类型主要由它的签名式(signature)决定,包括各个形式参数的名字、类型和返回值类型。值得注意的是,函数对象的返回值可以是void,这是void类型唯一可以出现的地方,而它的唯一可能取值是undefined。函数语义学TypeScript中的函数除了在JavaScript的函数对象模型的基础上添加了静态类型检查,体现了函数的数据方面之外,还在函数本身的性质上增加了不少新特性,例如函数缺省参数值:它会对应地生成以下的JavaScript目标代

11、码,从这里可以清晰地看到它生成代码的逻辑是通过判断参数有无定义来进行的:TypeScript支持有限的函数重载,为何说是有限的呢?因为一般意义上的函数重载是根据函数签名式的不同,在函数被实际调用时根据实际参数的类型来绑定到特定的重载函数的。其背后的实现机制,大多数是所谓的名称重整(name mangling)。但TypeScript中的函数重载不能这样做,它只支持能够以共用实现体为基础的重载,无论声明了多少个同名且签名式不同的函数,它都只能有一个实现体,且这个实现体必须对所有的重载版本都有意义。这样说可能比较令人费解,看个例子好了:只要看一下上述TypeScript代码生成的JavaScrip

12、t目标代码,就明白了大半:原因就在于TypeScript在实现重载时并没有使用名称重整机制,而JavaScript又不支持重载,所以只能做出这样非常大的折中方案了。TypeScript中最引人注目的一个函数对象特性是支持所谓的“箭头记法”(arrow notation),即Lamda表达式。例如下面的三个函数是等价的:但箭头记法最重要的用途还是在需要使用回调函数的场合。此时最易犯的一个错误就是this的作用域并非保留在被调用函数所在的局部作用域,而成了函数调用方所在的作用域。还是通过一个例子来看:此时,点击页面,弹出的警告框显示的值是“NAN”,显然有问题。而问题就出在这里的this指的是函数

13、调用方作用域,此处成了全局作用域,结果自然不对。此时只要改用箭头记法,问题就迎刃而解:这个记法是ECMAScript 6引入的,查看一下TypeScript生成的目标代码,就可以了解它是采用了迂回的办法在实现达到效果的同时又保持向下的兼容性。class和继承语义学TypeScript对JavaScript对象模型最重要的扩充,自然在于它补充了JavaScript中所没有引入的“类”的概念。是的,在JavaScript中没有类,只有对象,要实现所谓的“类式操作”(classical operations),如封装、多态等,要通过若干基础设施,如原型、构造函数等来完成。这些对于非常熟悉JavaSc

14、ript的程序员来说,也许都是可以完成的任务,但对于新手来说就困难重重了。并且,即使是高手,一段时间不写相关的代码也很容易遗忘和出错。但TypeScript却提供了标准的机制,将普通程序员熟悉的、C+和C#中常用的类概念映射到JavaScript中去,这样就大大降低了在JavaScript进行类式操作的难度。由于相关的概念理解起来并不困难,但技术内容却非常多,所以这里只介绍几点较关键的。首先,用一句话来概括在TypeScript中class的核心语义:所有的class都是一个立即函数,所有的数据成员都是这个函数实例的属性,所有的方法都是这个函数原型的属性,所有的静态成员都是这个函数的构造函数的

15、属性。各就各位,不会出错。只要看一下class生成的JavaScript目标代码就很明了,假设有个根据工龄计算工资的Human类定义如下:它生成的JavaScript目标代码如下:值得说明的是,TypeScript支持所谓的“存取器”。采用存取器,可以将函数封装,并且以数据属性的形式暴露出来。例如可以为上述类增加一个获取工资数额的存取器:对应的JavaScript代码比较复杂,浏览器需要支持ECMAScript 5才能运行:代码组织和重构TypeScript中引入了模块的概念,这类似于C+中的名字空间。它可以把声明、数据、函数和类封装在模块中,并采用export关键字导出,供模块外部的代码取用

16、。之所以说它和命名空间比较相似,一是因为同名的模块可以自动合并,甚至可以分别存储在多个文件中;二是因为模块的名字可以分成不同层次,在层次较多时还可以命名简化的别名。但无论模块怎么组织,最终生成的还是标准的、可直接取用的JavaScript代码。正是靠着模块化、可插拔的结构,TypeScript才得以在维护一个较小的语言核心的前提下,对广泛使用的库如jQuery、CommonJS和Node.js等提供了完整的支持。由于TypeScript并不是采用字符串匹配的粗糙方式来推导变量和函数的名字,对TypeScript代码进行命名的重构就如同微软的其他编程语言一样容易。只需要选中要重新命名的实体,并键入新的名字,而不需要担心名字相同而意义不同的其他实体也被同时重命名了。小结TypeScript是现今所有对JavaScript的改进中,唯一完全兼容并作为它的超集存在的解决方案。并且,TypeScript几乎是改进了JavaScript对象模型的方方面面,本文介绍的只是其中比较重要的一部分技术,还有很多细节还需要读者自己去探索。现在,TypeScript的最新版本是0.8.1,并且开放了全部的源代

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论