1.TypeScript简介
typescript是Javascript超集,是JavaS+强类型cript
TypeScript增加了什么
TypeScript 包含 ECMAScript 2015 (ES6) 的大部分特性,例如箭头函数。面向对象的语言:TypeScript 提供所有标准的 OOP 功能,如类、接口和模块。
TypeScript 使用静态类型并帮助在编译时进行类型检查。因此,你可以在编写代码时发现编译时错误,而无需运行脚本。
TypeScript 编译器可以安装在任何操作系统上,包括 Windows、macOS 和 Linux。
2.TypeScript开发环境搭建
cnpm install -g typescript
创建建一个ts后缀文件 如:hello.js
编译运行:
tsc hello.ts ---将ts文件编译为js文件
node hello.js ---运行js文件
案例
function foo(a:number,b:number){
return a+b;
}
let result = foo(1,2);
console.log(result);
3.TypeScript 基础类型
3.1类型声明
//声明一个变量a,同时指定它的类型为number
let a: number
//a的类型设置为number,在以后的使用过程中a的值只能是数字
a = 10;
a = 33;
//a='hello'//此行代码会报错 因为a的类型是number,不能赋值字符串
let b: string
b = 'hello'
//声明完变量直接进行赋值
let c: boolean = false
c = true;
// c=1;//报错
//如果变量的声明和赋值是 同时进行的,Ts可以自动对变量进行类型检测
let d = true;
d = false;
// d=1;//报错
3.2基础类型
//字面量
let x: 10;
x = 10;
// x=11;//已经规定x=10
//可以使用 | 来连接多个类型
let y: 'male' | "female"
y = 'male';
y = 'female';
let z: boolean | string
z = true;
z = 'hello'
//any 表示任意类型 一个变量设置类型为any后相当于对该变量关闭ts的类型检测
//使用ts是不建议使用any类型
let e: any
e = 10;
e = 'hello'
e = true;
//声明变量如果不指定类型则 TS解析器会自动判断变量的类型为any
let f;
f = 10;
f = true;
f = 'hello'
//unknown 表示未知的类型
let g: unknown;
g = 10;
g = 'hello'
g = true;
//any和unknown区别
let s: string
//e的类型是any。它可以赋值给任意类型
s = e;
//unknown 类型的值,不能直接赋值给其他变量
// s=g //报错
// 类型断言,可以用来告诉解析器变量的实际类型
s = g as string
// 语法:
// 变量 as 类型
// <类型>变量
// 元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同。
let h: [string, number]
h = ['hello', 1]
console.log(h); //['hello',1]
console.log(h[0]); //hello
console.log(h[1]); //1
// `enum`类型是对JavaScript标准数据类型的一个补充。
enum Direction { Up = "UP", Down = "DOWN", Left = "LEFT", Right = "RIGHT", }
// 某种程度上来说,`void`类型像是与`any`类型相反,它表示没有任何类型。 当一个函数没有返回值时,你通常会见到其返回值类型是`void`
function foo(): void { console.log('this is foo'); } foo();
//never 表示永远不会返回结果
// object表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型。
let o: object;
o = { name: 'terry' }
console.log(o);
//{}用来指定对象中可以包含那些属性
//语法 {属性名:属性值}
//加上一个问号表示属性可选
let ts: { name: string, age?: number }
ts = { name: '孙悟空', age: 10 }
4 面向对象
类可以理解为对象的模型,程序中可以根据类创建指定类型的对象
4.1.定义类
class 类名 {
属性名:类型;
constructor(参数:类型){
this.属性名=参数
}
方法名(){
...
}
}
案例:
对象中主要包含了两个部分
属性
方法
// 对象中主要包含了两个部分
// 属性
// 方法
class Person {
/*
直接定义的属性是实例属性 需要通过对象的实例去访问
*const person =new Person();
*person.name
person.sayHello()
*使用 static 开头的属性是静态属性(类属性) 可以直接通过类去访问
* Person.name
方法 Person.sayHello()
* readonly开头属性表示一个只读的属性无法修改
*/
//定义属性
name: string = '孙悟空';
//在属性前使用static 关键字可以定义属性(静态属性)
static readonly age: number = 18;
//方法
sayHello() {
console.log('hello');
}
}
const person = new Person();
// console.log(person);
// console.log(person.name, person.age);//孙悟空 18
// person.name = '呆子'
// console.log(person.name)
// Person.age='19' //报错 只读
//方法调用
person.sayHello()
4.2.构造函数
class Dog {
name: string;
age: number;
//coustructor
//构造函数会在对象创建时调用
constructor(name: string, age: number) {
// console.log('构造函数立即执行');
//在实例方法中 this表示当前对象实例
//在构造函数中当前对象就是当前新建的那个对象
//可以通过this向新建的对象添加属性
// console.log(this);
this.name = name
this.age = age
}
back() {
// console.log('汪汪汪');
console.log(this);
}
}
const dog = new Dog('小明', 18);
const dog1 = new Dog('小黒', 18);
// console.log(dog);
// console.log(dog1);
dog.back()
dog1.back()
4.3.继承
(function () {
// 定义一个Animal类 父类
class Animal {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name
this.age = age
}
sayHello() {
console.log('动物在叫');
}
}
//定义一个Dog的类(子类) 继承Animal 类
class Dog extends Animal {
run() {
console.log('${this.name}在跑');
}
//变成自己的
sayHello() {
console.log('狗在叫');
}
}
//定义一个猫的类(子类) 继承Animal 类
class Cat extends Animal {
//变成自己的
// // 重写 如果子类中方法签名与父类一致 则会对父类方法进行重写
sayHello() {
console.log('猫在叫');
}
}
const dog = new Dog('小敏', 19)
console.log(dog);
const at = new Cat('小黒', 19)
})();
4.4.super
(function () {
// 定义一个Animal类 父类
class Animal {
name: string;
constructor(name: string) {
this.name = name
}
sayHello() {
console.log('动物在叫');
}
}
//定义一个Dog的类(子类) 继承Animal 类
class Dog extends Animal {
age: number
//重写
constructor(name: string, age: number) {
//如果子类写了构造函数
super(name)//调用父类构造函数,在子类的构造函数中必须对父类的构造函数进行调用
this.age = age
}
//变成自己的
sayHello() {
//在类的方法中super就表示当前类的父类
super.sayHello()
}
}
const dog = new Dog('小敏', 19)
console.log(dog);
dog.sayHello()
})();
4.5.修饰符
TypeScript 里面定义属性的时候给我们提供了 三种修饰符
- public:公有类型,在当前类里面、子类、类外面都可以访问
- protected:保护类型,在当前类里面、子类里面可以访问,在类外部没法访问
- private:私有类型,在当前类里面可以访问,子类、类外部都没法访问
class Person2{
public name:string;
protected age:number;
private weight:number;
protected foo(){
console.log(this.name);
console.log(this.age);
console.log(this.weight);
}
constructor(name:string,age:number,weight:number){
this.name=name;
this.age=age;
this.weight=weight;
}
}
class Student2 extends Person2{
constructor(name:string,age:number,weight:number){
super(name,age,weight)
}
bar(){
// super 父类实例得引用
// console.log(super.age);
super.foo()
}
}
let s3=new Student2('terry',12,50);
s3.bar()
console.log(s3);
console.log(s3.name);
4.6.抽象类
- 什么是抽象类? 一般情况下,抽象类无法创建对象,抽象类中可以存在抽象方法,没有方法体得方法就是 抽象方法只有抽象签名,抽象类中可以存在抽象方法和非抽象方法,一个类中具有抽象方法, 那个该类一定是抽象类
- 存在得意义? 为了让其它类继承抽象类,并强制要求子类实现抽象方法;
- 子类继承抽象类 1.子类必须实现抽象类中得方法 2.子类成为抽象类
(function () {
// 定义一个Animal类 父类
// 只要继承抽象类
// 1.子类必须包含抽象类中得抽象方法
abstract class Animal {
name: string;
constructor(name: string) {
this.name = name
}
//定义一个抽象方法
abstract sayHello(): void
}
//定义一个Dog的类(子类) 继承Animal 类
class Dog extends Animal {
//子类必须重写 必须继承该方法
sayHello() {
console.log('汪汪汪');
}
}
const dog = new Dog('小敏')
console.log(dog);
dog.sayHello()
})();
4.5.接口
TypeScript的核心原则之一是对值所具有的结构进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约。
接口可以理解为是抽象到极致的抽象类,接口中只能存在抽象方法和属性。接口通过interface关键字来声明;
接口是需要实现得 类是可以继承
类实现接口必须具有接口得属性和方法,方法一般情况为一个没有方法体得方法
定义接口
interface I接口名{
规定的属性名: 类型;
规定的方法名(参数:数据类型):返回值;
实现接口
class 类型名 implements I接口名{
//必须包含接口中规定的属性和方法
}
(function () {
interface StudentInterFace {
name: string;
say(msg: string): void //未实现方法
}
class Student implements StudentInterFace {
name: string;
constructor(name) {
this.name = name
}
say(msg: string): void {
console.log(this.name + '说' + msg);
}
foo() {
}
}
let student: StudentInterFace = new Student('terry');//父类得引用指向子类实例
student.say('hello');
})();
5.总结
1.子类继承父类,通过父类类型引用可以指向子类对象吗?[可以] class Child extends Parent{ } let c1:Person=new Child()
2.通过父类类型得引用可以调用子类得特性吗?[不可以]
3.什么是重写? 子类继承父类?子类中方法的签名与父类一致,子类的方法回重写父类得方法 就近原则
4.如果子类对父类进行了重写,通过父类类型引用指向子类体现谁的特点?(子类方法)
5.什么是抽象类? 1.无法实例化 2.抽象类存在抽象方法和非抽象方法 3.如果一个类中包含了抽象方法,该类一定是抽象类 4.如果一个类继承了抽象类,并且这个抽象类中有多个抽象方法 那么子类1.实现所有的抽象方法 2.成为抽象类
6.什么是接口?接口就是抽象到极致的抽象类 如果一个类实现了接口,那么这个类需要将接口中所有未实现方法进行实现
7.如何实现一个接口
class Student implements StudentInterFace{}
8.接口可以继承吗?
子接口可以将父接口中所有的未实现方法进行继承
9.在ts中,可以进行多继承吗?可以进行多实现吗?