TypeScript 学习一 参数,函数,析构表达式

时间:2023-12-17 18:24:02

1,TypeScript是由微软开发的,不过新出的Angular2框架就是谷歌公司由TypeScript语言编写的,所以现在TypeScript是有微软和谷歌一起支持的;

2,TypeScript在javascript基础上扩充,任何javascript程序都可以不加修改的拿到typescript环境下运行;

3,ES是客户端脚本语言的规范,ES5和 ES6是这个规范的不同版本,javascript和typescript是客户端脚本语言,javascript实现了ES5规范,typescript实现了ES6规范;ES5的语法即代表javascript的语法,ES6即代表typescript的语法;

3,TypeScript的优势:

1)支持ES6的规范(指出了未来客户端脚本语言的发展方向);

2)强大的IDE支持(体现在三个特性上):

  1)类型检查;

  2)语法提示;

  3)重构;体现在修改一个变量,其他引用此变量的代码会自动修改;

3)是Angular2的开发语言,可以更好的理解Angular2;

4,搭建TypeScript环境:

就是搭建compiler(编译器): 作用是将TypeScript编译成javascript语言;

为什么用compiler? 因为ES6规范是2015年发布的的,到2016年,一些主流浏览器还未完全支持ES6,所以需要转换成javascript才能在浏览器中跑;

1)使用在线compiler:

百度搜索Typescript,到官网上找到学习乐园,点进去即看到在线compiler界面;

或者是  http://www.typescriptlang.org/play/index.html

2)本地compiler:(需要先下载node.js)

实际开放中,多数利用本地compiler,使用npm(node package manager  包管理器)下载compiler到本地;所以要想使用本地compiler就先下载nodejs到本地,自然就有npm了,可以使用npm -version 检测npm的版本;

在命令行里使用npm install -g typescript  下载typescript,得到tsc 即compiler;

5,TypeScript字符串新特性:

1)多行字符串:

传统的javascript中,若是将字符串换行表示,需要在中间利用加号来衔接,可读性不好;所以typescript引入了多行字符串的概念;

利用双撇号来声明字符串就不会出现换行的问题了,双撇号就是数字键盘1做左边的符号;被翻译成javascript的时候,就会自动加上换行符 \;

2)字符串模板:在多行字符串里通过表达式来声明变量或插入方法;表达式的格式就是 ${ 表达式名称 }

在编译器中编译后得到的javascript代码会很清晰明了;

例:在compiler中写入如下代码,注意双撇号的使用:

TypeScript 学习一   参数,函数,析构表达式

注意 ${} 这种写法必须用在撇号的内部才会被解析,若是在双引号内部,只会被原样显示为字符串的形式;

例:使用;撇号来声明常用的标签:

TypeScript 学习一   参数,函数,析构表达式

3)第三个特性就是自动拆分字符串:

使用字符串模板去调用一个方法的时候,字符串模板里的表达式的值会自动赋给被调用方法中的参数。

整个模板会被切成一个数组放到被调用的方法的第一个参数里,使用的两个表达式的最终评估处理的值放到被调用方法的后两个参数中;

注意:调用方法的时候,传统的是 ''方法名()''  ,但此处不用小括号,直接写  方法名`hello ${myname}, i'm${getAge}`

例:

TypeScript 学习一   参数,函数,析构表达式

5,参数新特性:

1)第一个参数新特性:在参数名称后面使用冒号来指定参数类型;

5种基本类型:string,any,number,boolean,自定义类型(class和接口声明),方法的返回值类型:void,此时的方法不需要返回值,

方法的参数类型的声明也是如此,调用方法时注意参数类型是否匹配;

变量类型的声明:

var myname : string = "LEE";

这样如果在后面给myname赋值时,如果类型不匹配,就会报错,这就是传说中的TypeScript的类型检查;

但是这种报错只会在typescript的编辑器里出现,javascript不会报错;

typescript还有一个机制---类型推断机制(当第一次为变量声明值后(即使未声明类型),会自动推断该变量的类型,以后如果再给该变量赋值,不是同种类型的话会报错)

例:

var ali="hhhhh";

ali=13;  //此时会报错

如果想让一个变量既可以声明为字符串,又可以声明为数字甚至其他类型,则可以将其声明为any类型;

var  ali: any ="hhhhh"; //声明为any后,就可以再将其声明为其他类型的如数字了;

除了以上的5类型之外,typescript还有通过class和接口自定义的类型;

例:

class Person{

  name :string;

  age : number;

}

var zhangsan:Person =new Person(); //此时 可以 声明一个Person类型的变量zhangsan

再输入zhangsan 时 ,就会有语法提示,zhangsan.name , zhangsan.age 有助于提高效率;

接口定义的类型,见TypeScript 学习之面向对象新特性 文章;

2)第二个参数新特性:

在参数声明后面用等号来指定参数的默认值;这个就是普通的var a : string = "hhhh"; //此处的等号用来指定默认值,后面的即为默认值;

另一个就是给方法的变量指定默认值;注意,指定默认值的参数要声明在最后面;

正常的声明一个带参数的方法后,调用该方法时传入参数的个数必须和方法声明时的参数个数相同,否则会报错,此时如果将其中某个参数指定默认值,则调用时参数的个数和原方法参数个数不同,也不会报错;

例:

TypeScript 学习一   参数,函数,析构表达式

将第三个参数 指定了默认值18,在调用方法时,不传第三个参数,也不会报错了:

TypeScript 学习一   参数,函数,析构表达式

但是要注意:指定默认值的参数一定要声明在最后面;

否则,如果第一个参数指定了默认值,但是调用方法传参的时候,只传了两个参数,那是传了前两个参数,最后的参数没穿,会报错的;

6,函数新特性:

为函数定义类型时,先给参数加类型,然后再给函数本身加类型;typescript能根据返回语句自动推断返回值类型,因此通常忽略它;

匿名函数类型:使用箭头,在函数和返回值类型之前使用=>,

完整的函数类型包括参数类型和函数类型:只要参数类型匹配,就是有效的函数,不用在乎参数名是否正确;

function add( num1:number , num2:number ) :number{

  return num1+num2;

}

1)第一个新特性是Rest and Spread 操作符:用来声明任意数量的方法参数:通过使用三个点 ( . . . );

TypeScript 学习一   参数,函数,析构表达式

TypeScript 学习一   参数,函数,析构表达式

Rest and Spread 还可以反过来用;如下

TypeScript 学习一   参数,函数,析构表达式

如上所见,在typescript(有些版本暂不支持),但是javascript中仍然能运行,运行后的结果就是:

TypeScript 学习一   参数,函数,析构表达式

方法一中没有传第三个参数,所以是未定义,方法二中将前三个参数传递了,因为方法定义中只有三个形参;

2)函数的第二个新特性:generator函数,控制函数的执行过程,手工暂停和恢复代码执行;

generator函数就是在function的后面加上星号,function*  , 并且与yield关键字,next()方法结合使用;并且在调用该方法时,需要将该方法声明为一个变量再调用;

执行过程:每调用一次next()方法,就执行到yield关键字处停止,再次调用next()方法时,再从yield关键字处开始继续执行,直到下一个yield关键字为止;yield关键字相当于打断点

这个特性有的版本的typescript不支持,所以去搜索babel这是个编辑器(也是两侧显示代码的),使用它来写下:

TypeScript 学习一   参数,函数,析构表达式

3)函数的第三个新特性:destructuring析构表达式:通过表达式 将对象或数组拆分成任意数量的变量;

一:使用表达式将对象进行拆分:使用大括号声明析构表达式

正常的ES5规范也就是javascript语法中,声明变量需要如下图中7,8,9行声明,但是ES6规范也就是typescript中使用析构表达式则只需要第11行一行代码即可表示;对应右边的第10行,分别将各变量解析出来了;

TypeScript 学习一   参数,函数,析构表达式

注意1)如果想要在打印时,将变量以别名的形式打出来:在使用表达式的时候使用冒号即可添加本地变量的别名:如下图中第11行代码所示;

TypeScript 学习一   参数,函数,析构表达式

注意2):如何取一个嵌套的属性;就是在析构表达式里再嵌套析构表达式;

例:如果price对象下有两个嵌套的属性price1和price2 ,注意逗号分隔,则可以使用冒号和嵌套析构表达式 来获得 嵌套属性中的某个单独的属性;

意思就是通过price2变量获得千套属性中price2属性;

TypeScript 学习一   参数,函数,析构表达式

注意3):假如还存在一些其他没有使用析构表达式的属性,但并不影响析构表达式的使用;

TypeScript 学习一   参数,函数,析构表达式

二:使用表达式将数组进行拆分:使用方括号对析构表达式声明;只想输出部分值的时候使用

1)

TypeScript 学习一   参数,函数,析构表达式

上图中打印出来的num1和num2分别是1和3;

var [  ,  ,num1,nm2 ] = arr ;  //这样打印出来的是3和4;

var [num1,num2,   ,   ] = arr ; //这样打印出来的是1和2;

var [num1 ,   ,   ,   ] =arr ; //这样打印出来的是1 ;

2)数组中的析构表达式和Rest and Spread 操作符(用来声明任意数量的方法参数)结合使用;

TypeScript 学习一   参数,函数,析构表达式

运行结果为:

TypeScript 学习一   参数,函数,析构表达式

说明Rest and Spread 操作符此处将剩余的两个元素放到了others数组里面了,

3)将析构表达式作为方法的参数使用:

TypeScript 学习一   参数,函数,析构表达式

执行结果是和上例中相同的,也是将后两个参数放到了others数组里面;

7,变量声明时,使用let 和 var 的区别:

let:使用let 声明一个变量时,使用的是词法作用域或块作用域;不同于使用var声明的变量那样可以在包含它们的函数外访问;块作用域变量在包含它们的块或for循环之外是不能访问的;并且不能在声明之前被读写(typescript会提示);

8,屏蔽:在一个嵌套的作用域里引入一个新名字的行为称为屏蔽;

function sumMatrix(matrix: number[][]) {
let sum = 0;
for (let i = 0; i < matrix.length; i++) {
var currentRow = matrix[i]; //如果没有这句屏蔽,则会报错,因为两个嵌套的for循环里的i重复了
for (let i = 0; i < currentRow.length; i++) {
sum += currentRow[i];
}
} return sum;
}

9,基本类型:布尔类型,数字类型,字符串类型,枚举类型,自定义类型,any类型,空值(undefined ,null);

布尔类型:就是true或false;

数字类型:typescript里的所有数字都是浮点数,就是number类型,除了支持十进制和十六进制(0x开头),还支持二进制和八进制(0o或者是0);

字符串类型:以双引号或单引号括起;

枚举类型enum:枚举类型的便利就是可以通过枚举值找到名字;

enum Color{Green , Yellow ,Black};

let c:Color = Color.Green;

默认情况从0开始赋值,但也可以手动给某个元素或全部元素的编号赋值;

enum Color {Red=1 , Yellow, Black};  //手动给某个元素编号,现在就从编号1开始赋值了

let c: Color = Color.Green;

enum Color {Red = 1, Yellow = 2, Black = 3}

let c: Color = Color.Green;   //手动给全部元素编号;

例:通过枚举值找到名字:

enum Color {Red = 1, Yellow ,Black};

let colorName:string =Color[2];

alert(colorName);

10,数组:定义有两种方式:

let list :number[] = [1,2,3,4];

let list : Array<number> = [1,2,3,4];

11,元组Tuple:

元组允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。

let x : [ string , number];

x = ['hello' ,100 ] ;  //而不能是x = [100,'hello']

console.log( x[0].substr(1));  //是正确的;

console.log( x[1].substr(1));     //是错误的,number类型没有子串

12,类型断言:好比其他语言里的类型转换,但不进行特殊的数据检查可解构;

类型断言有两种方式:其一是尖括号语法;

let someValue : any = "this is a string";

let strLength : number = (<string>someValue).length;

其二是as语法:

let someValue : any = "this is a string";

let strLength :number = (someValue as string).length;

13,当在类里使用this的时候,说明使用this引用的就是类成员;