typescripts学习
可选与默认参数
可选参数:在参数名后面,冒号前面添加一个问号,则表明该参数是可选的。如下代码:
- function buildName(firstName: string, lastName?: string) { //lastName为可选参数
- if (lastName)
- return firstName + " " + lastName;
- else
- return firstName;
- }
- var result1 = buildName("Bob"); //正确调用 Bob
- var result2 = buildName("Bob", "Adams"); //正确调用 Bob Adams
默认参数:在参数名后直接给定一个值,如果这个值没有被传入,那么将会被赋值为默认值。如下代码:
- function buildName(firstName: string, lastName = "Smith") {
- return firstName + " " + lastName;
- }
- var result1 = buildName("Bob"); //没有传入第二个参数,则被赋值为默认的smith,结果为:Bob Smith
- var result2 = buildName("Bob", "Adams"); //结果为:Bob Adams
注:可选参数和默认参数必须在参数列表的最后。
继承
TypeScript中用关键字extends指明继承关系。例如,已经定义了类A,如果让类B继承A,我们把A叫做基类,B叫子类。可以用下面的方式定义类B。
- class B extends A {
- // 类B中的成员
- }
如果我们要在子类中调用基类中的属性与方法就要使用super关键字。如下代码:
- class Animal { //定义基类
- name:string;
- constructor(theName: string) { this.name = theName; }
- move(meters: number) {
- document.write(this.name + " moved " + meters + "m.");
- }
- }
- class Snake extends Animal { //继承基类
- constructor(name: string) {
- super(name); //调用基本类的构造函数
- }
- move() { //重写了基类的方法
- document.write("Slithering...<br>");
- super.move(5); //调用基类的方法
- }
- }
- var sam = new Snake("Python"); //声明Snake类
- sam.move();
接口声明
在TypeScript中,接口是用作约束作用的,在编译成JavaScript的时候,所有的接口都会被擦除掉,因为 JavaScript中并没有接口这一概念。TypeScript中接口是用关键字interface进行声明,例如:
- interface LabelledValue { //定义接口
- label: string; //定义属性
- }
- interface LabelledValue { //定义接口
- label: string;
- }
- function printLabel(labelledObj: LabelledValue) { //定义函数printLabel,其参数类型为接口类型
- document.write(labelledObj.label);
- }
- var myObj = {size: 10, label: "Size 10 Object"}; //定义含有接口中属性的对象
- printLabel(myObj); //调用函数
可选属性
有时不是所有定义在interface中的属性都是必须的,typescript中便为我们提供了可选属性。带有可选属性的interface定义和c#语言很相似,以?紧跟变量名后边表示。如下代码:
- interface SquareConfig { //定义了两个可选属性
- color?: string;
- width?: number;
- }
- function createSquare(config: SquareConfig): {color: string; area: number} {//定义函数
- var newSquare = {color: "white", area: 100};
- if (config.color) {
- newSquare.color = config.color;
- }
- if (config.width) {
- newSquare.area = config.width * config.width;
- }
- return newSquare;
- }
- var mySquare = createSquare({color: "black"}); //调用函数,
- document.write(mySquare.color); //结果为: black
大家可能会问既然是可选属性,可有可无的,那么为什么还要定义呢?对比起完全不定义,定义可选属性主要是:如果存在属性,能约束类型,而这也是十分关键的。
方法类型
在 JavaScript 中,方法 function 是一种基本类型。在面向对象思想中,接口的实现是靠类来完成的,而 function 作为一种类型,是不是能够实现接口呢?答案是肯定的。在 TypeScript 中,我们可以使用接口来约束方法的签名。
- interface SearchFunc {
- (source: string, subString: string): boolean; //定义一个匿名方法
- }
- var mySearch: SearchFunc;
- mySearch = function(source: string, subString: string) { //实现接口
- var result = source.search(subString); //调用系统方法search查找字符串的位置
- if (result == -1) {
- return false;
- }
- else {
- return true;
- }
- }
上面代码中,我们定义了一个接口,接口内约束了一个方法的签名,这个方法有两个字符串参数,返回布尔值。在第二段代码中我们声明了这个接口的实现。编译器仅仅检查类型是否正确(参数类型、返回值类型),因此参数的名字我们可以换成别的。
数组类型
在前面一节中我们学习了接口定义方法类型,这一节我们来学习接口定义数组类型。在数组类型中有一个“index”类型其描述数组下标的类型,以及返回值类型描述每项的类型。如下:
- interface StringArray { //定义数组接口
- [index: number]: string; //每个数组元素的类型
- }
- var myArray: StringArray;
- myArray = ["Bob", "Fred"];
在接口的定义里面,索引器的名字一般为 index(当然也可以改成别的,但一般情况下都是保持名字为 index)。索引器的类型只能为 number 或者 string。
- interface Array{
- [myindex: number]: number;
- }
- interface Dictionary{
- [index: string]: any;
- }
Class类型
在C#和java中interface是很常使用的类型系统,其用来强制其实现类符合其契约。在TypeScript中同样也可以实现,通过类实现接口要用implements关键字。如下代码:
- interface IPrint{
- print();
- }
- class A implements IPrint { //实现接口
- print(){ //实现接口中的方法
- document.write("实现接口");
- }
- }
- var B=new A();
- B.print();
接口继承
和类一样,接口也能继承其他的接口。这相当于复制接口的所有成员。接口也是用关键字“extends”来继承。
- interface Shape { //定义接口Shape
- color: string;
- }
- interface Square extends Shape { //继承接口Shape
- sideLength: number;
- }
一个interface可以同时继承多个interface,实现多个接口成员的合并。用逗号隔开要继承的接口。
- interface Shape {
- color: string;
- }
- interface PenStroke {
- penWidth: number;
- }
- interface Square extends Shape, PenStroke {
- sideLength: number;
- }
模块的声明
前端数据验证在改善用户体验上有很大作用,在学了前面的知识,我们很可能会写出以下代码:
- interface StringValidator { //定义验证接口
- isAcceptable(s: string): boolean;
- }
- var lettersRegexp = /^[A-Za-z]+$/;
- var numberRegexp = /^[0-9]+$/;
- class LettersOnlyValidator implements StringValidator { //实现接口
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- class ZipCodeValidator implements StringValidator { //实现接口
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- var strings = ['Hello', '98052', '101'];
- var validators: { [s: string]: StringValidator; } = {};
- validators['ZIP code'] = new ZipCodeValidator(); //实例化类
- validators['Letters only'] = new LettersOnlyValidator(); //实例化类
- for(var i=0;i<strings.length;i++){
- for (var name in validators) {
- document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); //调用类的方法
- }
- }
那么这段代码最大的问题是什么呢?一个是没法复用,验证的封装和验证过程在同一个文件,验证的封装已经是可以复用的。另一个是接口和两个实现的类都直接挂接在全局变量上,假如数量一多的话,将会影响整个全局变量。
而TypeScritp中模块的出现给我们解决了这一问题。使用 module 关键字来定义模块,并在末尾加花括号即可用; 用export 关键字使接口、类等成员对模块外可见。
- module Validation { //定义模块
- export interface StringValidator { //声明接口对外部可以使用
- isAcceptable(s: string): boolean;
- }
- var lettersRegexp = /^[A-Za-z]+$/;
- var numberRegexp = /^[0-9]+$/;
- export class LettersOnlyValidator implements StringValidator { //声明类对外部可用
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- export class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- }
模块内容的调用
在前面一节中我学习了模块的声明,而在模块声明完成以后,我们就可以调用这个模块了,调用模块中的接口、类、方法等。调用方法简单,就是用模块名后面跟一个点来调用类、接口、方法等。如下代码:
- module Validation { //定义模块
- export interface StringValidator { //声明接口对外部可以使用
- isAcceptable(s: string): boolean;
- }
- var lettersRegexp = /^[A-Za-z]+$/;
- var numberRegexp = /^[0-9]+$/;
- export class LettersOnlyValidator implements StringValidator { //声明类对外部可用
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- export class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- }
- var strings = ['Hello', '98052', '101'];
- var validators: { [s: string]: Validation.StringValidator; } = {};
- validators['ZIP code'] = new Validation.ZipCodeValidator(); //使用模块中的类
- validators['Letters only'] = new Validation.LettersOnlyValidator();
- // 显示匹配结果
- for(var i=0;i<strings.length;i++){
- for (var name in validators) {
- document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); // 使用方法
- }
- }
分隔模块到多个文件
随着我们项目的扩展,我们的代码总不可能只写在一个文件里。为了更好地维护项目,我们会将特定功能放到一个文件里,然后加载多个文件实现我们想需要的功能。现在我们先将上面的代码分割到多个文件里。
Validation.ts
- module Validation {
- export interface StringValidator {
- isAcceptable(s: string): boolean;
- }
- }
LettersOnlyValidator.ts
- /// <reference path="Validation.ts" />
- module Validation {
- var lettersRegexp = /^[A-Za-z]+$/;
- export class LettersOnlyValidator implements StringValidator {
- isAcceptable(s: string) {
- return lettersRegexp.test(s);
- }
- }
- }
ZipCodeValidator.ts
- /// <reference path="Validation.ts" />
- module Validation {
- var numberRegexp = /^[0-9]+$/;
- export class ZipCodeValidator implements StringValidator {
- isAcceptable(s: string) {
- return s.length === 5 && numberRegexp.test(s);
- }
- }
- }
Test.ts
- /// <reference path="Validation.ts" />
- /// <reference path="LettersOnlyValidator.ts" />
- /// <reference path="ZipCodeValidator.ts" />
- var strings = ['Hello', '98052', '101'];
- var validators: { [s: string]: Validation.StringValidator; } = {};
- validators['ZIP code'] = new Validation.ZipCodeValidator();
- validators['Letters only'] = new Validation.LettersOnlyValidator();
- for(var i=0;i<strings.length;i++){
- for (var name in validators) {
- document.write('"' + strings[i] + '" ' + (validators[name].isAcceptable(strings[i]) ? ' matches ' : ' does not match ') + name+"<br>"); //调用类的方法
- }
- }
在项目中新建好以上四个文件,然后我们编译项目,如果我们代码编写没错的话,是能够编译通过的。另外,我们可以见到后面三个文件开头有类似于 C# 的文档注释,这是告诉 TypeScript 编译器该文件依赖于哪些文件,假如依赖的文件不存在的话,编译就会不通过。当然我们不写也是可以的,只不过编译器在编译时不会帮我们检查,一般来说,还是建议写上。 另外,在引用编译生成的 JavaScript 文件时,我们需要注意好顺序。以上面的代码为例,我们在 Html 代码中已经这么引用。
- <script src="Validation.js" type="text/javascript"/>
- <script src="LettersOnlyValidator.js" type="text/javascript"/>
- <script src="ZipCodeValidator.js" type="text/javascript"/>
- <script src="Test.js" type="text/javascript"/>
typescripts学习的更多相关文章
- 从直播编程到直播教育:LiveEdu.tv开启多元化的在线学习直播时代
2015年9月,一个叫Livecoding.tv的网站在互联网上引起了编程界的注意.缘于Pingwest品玩的一位编辑在上网时无意中发现了这个网站,并写了一篇文章<一个比直播睡觉更奇怪的网站:直 ...
- Angular2学习笔记(1)
Angular2学习笔记(1) 1. 写在前面 之前基于Electron写过一个Markdown编辑器.就其功能而言,主要功能已经实现,一些小的不影响使用的功能由于时间关系还没有完成:但就代码而言,之 ...
- ABP入门系列(1)——学习Abp框架之实操演练
作为.Net工地搬砖长工一名,一直致力于挖坑(Bug)填坑(Debug),但技术却不见长进.也曾热情于新技术的学习,憧憬过成为技术大拿.从前端到后端,从bootstrap到javascript,从py ...
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- Unity3d学习 制作地形
这周学习了如何在unity中制作地形,就是在一个Terrain的对象上盖几座小山,在山底种几棵树,那就讲一下如何完成上述内容. 1.在新键得项目的游戏的Hierarchy目录中新键一个Terrain对 ...
- 《Django By Example》第四章 中文 翻译 (个人学习,渣翻)
书籍出处:https://www.packtpub.com/web-development/django-example 原作者:Antonio Melé (译者注:祝大家新年快乐,这次带来<D ...
- 菜鸟Python学习笔记第一天:关于一些函数库的使用
2017年1月3日 星期二 大一学习一门新的计算机语言真的很难,有时候连函数拼写出错查错都能查半天,没办法,谁让我英语太渣. 关于计算机语言的学习我想还是从C语言学习开始为好,Python有很多语言的 ...
- 多线程爬坑之路-学习多线程需要来了解哪些东西?(concurrent并发包的数据结构和线程池,Locks锁,Atomic原子类)
前言:刚学习了一段机器学习,最近需要重构一个java项目,又赶过来看java.大多是线程代码,没办法,那时候总觉得多线程是个很难的部分很少用到,所以一直没下决定去啃,那些年留下的坑,总是得自己跳进去填 ...
随机推荐
- Java应用开发的一条重要经验:先建立基础设施
一旦为应用建立良好的基础设施, 后续的开发就会变得容易而快速.这些基础设施包括: 1. 线程池的建立与配置: 在 JDK 并发库的基础上建立适合于应用的多任务接口和框架: 2. 外部系统服务 ...
- SoapUI 使用变量
登录问题不好解决, 只能临时用cookie来执行 1.变量定义 2.引用变量 3.调用Header
- Selenium2+python自动化54-unittest生成测试报告(HTMLTestRunner)
前言 批量执行完用例后,生成的测试报告是文本形式的,不够直观,为了更好的展示测试报告,最好是生成HTML格式的. unittest里面是不能生成html格式报告的,需要导入一个第三方的模块:HTMLT ...
- C++原创应用类库和工具类库
此博文记载着自编C++应用类库和生成器库的源代码的链接地址,并且对库的开发环境.开发过程.缺陷以及改进更新进行说明. 分数类 利用中午的时间,自己在Visual Studio 2013环境下编写了一个 ...
- Linux基础命令---tune2fs
tune2fs tune2fs允许系统管理员在Linux ext2.ext3或ext4文件系统上调整各种可调的文件系统参数.这些选项的当前值可以使用-l选项显示,也可以通过使用dumpe2fs (8) ...
- Python3.x(windows系统)安装libxml2库
Python3.x(windows系统)安装libxml2库 cmd安装命令: pip install lxml 执行结果: 再执行命令: pip install virtualenv 执行结果:
- Github使用教程详解
官方网站:http://git-scm.com Git是目前世界上最先进的分布式版本控制系统(没有之一). Git有什么特点?简单来说就是:高端大气上档次! 一.Git安装 在Linux上安装Git ...
- hdu 1671 Phone List(字典树)题解
题意:给一连串数字,如果有前缀重复给出NO,否则给出YES 思路:这道题要delete否则爆内存,之前想的直接在insert()里解决查询有错误,所以先保存数据再查询. 代码: #include< ...
- 51NOD 1057 N的阶乘
1057 N的阶乘 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 输入N求N的阶乘的准确值. Input 输入N(1 <= N <= 10000) ...
- 使用PDFminer3k解析pdf为文字遇到:WARING:root:GBK-EUC-H
最近需要把PDF解析为文字,查了查python的模块,发现PDFminer3k能满足需求.我使用的是 windows平台下的python3.6,python2的则下载pdfminer. 首先下载:直接 ...