TypeScript简介:
微软开发 javascript的超集 遵循ES6脚本语言的规范
添加了遵循ES6的语法 增加了面向对象编程的特性
angular2是TypeScript编写的,angular2是Google公司所开发的。微软与谷歌共同支持TypeSript。
课程内容:
1.学习TypeScript的好处
2.安装习TypeScript的开发环境
3.TypeScript的概念/特性等
前置知识:
1.理解ES5、ES6、JavaScript、TypeScript的概念和关系
2.基础的javaScript的开发经验
TypeScript的优势:
1.支持ES6规范
2.强大的IDE(Integrated Development Environment 集成开发环境)的支持
(1)类型检查 指出类型错误
(2)语法提示 根据上下文,提示代码
(3)重构 对变量等等进行修改时,会对其它地方的相同变量等进行相应修改
3.Angular2的开发语言
搭建TypeScript开发环境
1.TypeScript 在线compiler的使用
原因: 现今主流浏览器的支持ES5的语法,所以需要将ES2015的语法转换为ES5的语法,即将TypeScript转化为JavaScript的语法。
2.TypeScript-本地compiler
(1)使用命令行工具转译TypeScript代码:
转到ts文件所在文件夹;
输入命令: tsc hello.ts
(2)在IDE中:(以webstorm为例)
点击: webstorm -> Preferences -> Languages & Frameworks -> TypeScript -> 选中 Enable TypeScript Compiler -> 点击 Apply -> 点击 OK
字符串新特性
1.多行字符串
var content = `aaa
bbb
ccc`;
使用``进行换行,转译后的代码为 var content = "aaa\nbbb\nccc";
2. 字符串模板
在多行字符串中插入变量或者表达式
var myname = 'zhai liang';
var getName = function () {
return 'zhai liang';
}
console.log(`hello ${myname}`);
console.log(`hello ${getName()}`);
console.log(`
${myname}
${getName()}
`);
编译后的结果:
var myname = 'zhai liang';
var getName = function () {
return 'zhai liang';
};
console.log("hello " + myname);
console.log("hello " + getName());
console.log("
\n" + myname + "\n" + getName() + "\n
");
将变量或者表达式放入: ${} 中
3. 自动拆分字符串
例子:
function test(template, name, age) {
console.log(template);
console.log(name);
console.log(age);
}
var myname = 'zhai';
var getAge = function () {
return 18;
}
test`hello my name is ${myname},i'm ${getAge()}`;
打印结果为:
Array(3)0: "hello my name is " 1: ",i'm "2: ""
zhai
18
当多行字符串调用方法时,方法会自动将变量或者表达式的值作为参数传入方法中;
同时,变量或者表达式会将多行字符串分割为数组的各个项,并将数组作为第一个参数传入方法中。
参数新特性:
1.参数类型:
(1)定义:在参数名称后面添加参数类型 例子:
var myname: string = 'yangfan';
其它的变量参数类型为 number boolean number
(2)变量推断机制: 当声明变量时,没有添加变量类型。当重新赋值时,会默认其对象类型为第一次赋值的类型;
例子: var myname = 'yangfan'; myname = 'fan'; 当添加其它类型数据时,会提示错误。
(3)特殊变量类型:any
var hel: any = 13; hel = 'yang'; 不会报错
(4)函数的参数类型:
function test(name: string): string { //
return name;
};
第一个参数类型为: 参数类型; 第二个参数类型为:返回值的类型;
(4)自定义类型:
构造函数:
class Person {
name: string;
age: number;
}
var yang: Person = new Person ();
yang.name = 'fan';
yang.age = 18;
2.参数默认值:
给函数参数指定类型后,当不传参/少传参时,会报错
可以给参数指定默认值:
function test(a: string, b: number, c: Boolean = false) {
console.log(a);
console.log(b);
console.log(c);
};
test('aaa', 1);
结果: 'aaa' 1 false;
** 注意**: 传默认值的参数应写在最后面
3.可选参数:
函数参数中可以指定可选参数,即不是必填的
function test(a: string, b?: number, c: Boolean = false) {
console.log(a);
console.log(b);
console.log(c);
};
test('aaa');
结果为 'aaa' undefined false;
**注意**: 可选参数必须放在必选参数之后
函数新特性:
1. Rest and Spread 操作符
作用:声明可以传任意数量参数的方法
例子:
function test(...args) {
args.forEach(function (arg) {
console.log(arg);
})
};
test(1, 2, 3);
test(5, 6, 7, 8, 9, 10);
打印结果:
1 2 3
5 6 7 8 9 10
2. generator函数
作用: 控制函数的执行进程,用于暂停、恢复函数执行
例一:
function* test(){
console.log(1);
yield
console.log(2);
}
var num = test();
num.next();
num.next();
描述: 必须使用变量接收函数,输入一次num.next();会执行一次函数;
当遇到yield时,会停顿。再次输入num.text(),则会再次执行。
例二:
function* test(){
while(true) {
yield Math.random()*100;
}
}
var num = 15;
var money = 100;
while(money > num) {
money = test().next().value;
console.log(`money is ${money}`);
}
console.log(`buy now ${money}`);
描述: 通过不断地循环从而不断地执行函数,过程一直在重复: 执行、打断
3.destructuring析构表达式:
该表达式作用: 将对象/数组拆解为任意数量的变量
例一:
function test() {
return {
name: 'yang',
age: 18
}
}
var {name, age } = test();
console.log(name);
console.log(age);
输出结果为: 'yang' 18
**注意**:声明的变量名必须与对象属性名相同
例二:
function test() {
return {
name: 'yang',
age: 18,
fruits: {
apple: 5,
banana: 8
}
}
}
var { name: myName, fruits: {apple} } = test();
console.log(myName);
console.log(apple);
输出结果为: 'yang' 5
注意:1.当有对象的嵌套时,也可输出整个对象,也可利用析构表达式输出对象的属性
2.可以给变量另取名字: name: myName
例三:
var arr = [1, 2, 3, 4];
var [,num1, num2,] = arr;
console.log(num1);
console.log(num2);
输出结果为:2 3
例四:
var arr = [1, 2, 3, 4];
var [, num1, num2, ...others] = arr;
console.log(num1);
console.log(num2);
console.log(others);
输出结果为: 2 3 [4]
总结: 析构表达式可以很方便的使用对象或数组中的属性、元素,来进行操作。
表达式和循环
1.箭头表达式:
声明匿名函数,消除传统匿名函数中的this指向问题
样式:
(1). 普通样式: var sum = (arg1,arg2) => {return arg1 + arg2};
(2).函数只有一行代码时,var sum = (arg1,arg2) => arg1 + arg2;
(3).只有一个参数时,var sum = arg => arg * 3;
(4).无参时,var sum = () => 1;
使用示例:
(1).选出偶数
var arr = [1, 2, 3, 4, 5, 6];
var arr2 = arr.filter(val => val % 2 == 0);
(2).this 指向:
var test = name => {
this.name = name;
setInterval(() => console.log(this.name),1000);
}
var obj = new test('yang');
其中定时器中的this指向被定义的对象,所以打印的是: 'yang'.
2.forEach()、for in 和 for of
var arr = [2, 3, 4];
arr.name = 'arrrrrrr';
arr.forEach(val => console.log(val));
结果为: 2 3 4 并没有 'arrrrrrr';
for (var val in arr) {
console.log(arr[val]);
}
结果为: 2 3 4 'arrrrrrr';
for (var n of arr) {
console.log(n);
}
结果为: 2 3 4;
for in 和 for of 的区别: for in 遍历的是键名,而for of 遍历的是键值。
另外,for of 可以使用break 来打断。,for of 还可以遍历对象、字符串。
for (var n of arr) {
if (n > 2) break;
console.log(n);
}
结果为: 2;
面向对象新特性:
1.typeScript 类:
(1).类的声明与使用:
class Person {
name;
run() {
console.log("i'm runing");
}
}
var you = new Person();
you.name = 'who';
you.run();
var him = new Person();
him.name = 'whooo';
him.run();
类的定义方式比较简单。
其中方法的声明转换成javaScript 为:
Person.prototype.run = function () {
console.log(name);
};
存入其Person.prototype中。
声明构造函数的访问权限:默认为 public 可选的为 private protected
默认:
class Person {
public name;
public run() {
console.log("i'm runing");
}
}
class Person {
private name;
private run() {
console.log("i'm runing");
}
}
class Person {
protected name;
protected run() {
console.log("i'm runing");
}
}
其中,public 是外部可以访问; private 是内部可以访问; protected是内部以及子类可以访问。
构造函数的constructor方法:该方法只会在实例化中执行一次:
class Person {
name;
constructor(name: string) {
this.name = name;
};
run() {
console.log(this.name);
};
}
var you = new Person('you');
you.run();
var him = new Person('him');
him.run();
结果为: 'you' 'him';
也可这样定义:
class Person {
constructor(public name: string) {
this.name = name;
};
run() {
console.log(this.name);
};
}
public 不能省;
(2). 类的继承 关键字: extends
class Person {
constructor(public name: string) {
this.name = name;
};
run() {
console.log(this.name);
};
}
class soldier extends Person{
clothes;
skills() {
}
}
var bing1 = new soldier('yang');
bing1.run();
bing1.clothes = 'fdfdf';
bing1.skills();
其中类soldier 会继承 类 Person 的所有方法、属性。
(3). 调用父类的属性和方法:
class Person {
constructor(public name: string) {
this.name = name;
console.log('haha')
};
run() {
console.log("i'm running");
};
}
class soldier extends Person{
constructor(name: string, clothes: string) {
super(name);
console.log('xixi')
this.clothes = clothes;
}
clothes;
skills() {
super.run();
this.kill();
}
private kill() {
console.log('kill enermy');
}
}
var bing1 = new soldier('yang','hat');
bing1.skills();
结果为: 'haha' 'xixi' "i'm running" 'kill enermy';
其中,一般是在子类的构造函数constructor 中调用父类的属性,且方式为:super(name);
调用父类的方法:super.run();
另外,注意 private关键字的用法。
2. TypeScript 泛型:
作用: 参数化的类型,用于限制集合的内容
class Person {
constructor(public name: string) {
this.name = name;
console.log('haha')
};
run() {
console.log("i'm running");
};
}
var arr: Array = [];
arr[0] = new Person('heee');
**其中,数组arr的元素只能为 Person 及其子类的对象。**
3. TypeScript 接口 关键字: Interface
(1)通过接口声明参数规范:
interface Iperson {
name: string;
age: number;
}
class Person {
constructor(public config: Iperson) {
}
}
var p1 = new Person({
name: 'yang',
age: 14
});
声明方法时,对方法参数的类型进行约束
(2)通过接口声明方法:
interface Animal {
eat();
}
class Sheep implements Animal {
eat(){
console.log('grass')
}
}
class Tiger implements Animal {
eat() {
console.log('meat')
}
}
在定义构造函数中,引入接口 (注意引入方式),就必须使用接口的方法。
4. 模块:
a.ts
var prop1;
export var prop2;
function f1(){};
export function f2(){};
class P1{};
export class P2{};
b.ts
import {f2, P2, prop2} from "./a";
console.log(prop2);
f2();
var person = new P2();
总结: 模块以文件为单位,可将代码分割、重用,并可决定暴露的部分。
5.注解:
不太理解,需要在实际项目中体会
6.类型定义文件: .d.ts
将工具文件命名的后缀改为: .d.ts