目录
TypeScript类
TypeScript是面向对象的JavaScript,类描述了所创建的对象共同的属性和方法
TypeScript类定义方式如下:
class [类名] {
// 类作用域
}
创建类的数据成员
我们将创建一个类,并且创建几个“字段”、“方法”、“构造函数”
TS代码:
class Car {
// 字段
engine: string;
// 构造函数
constructor(engine: string) {
this.engine = engine;
}
// 方法
disp(): void {
console.log("Engine is " + this.engine);
}
}
JS代码:
var Car = /** @class */ (function () {
// 构造函数
function Car(engine) {
this.engine = engine;
}
// 方法
Car.prototype.disp = function () {
console.log("Engine is " + this.engine);
};
return Car;
}());
创建实例化对象
使用new关键字来实例化类的对象
let myCar = new Car("V8");
// 访问属性
console.log(myCar.engine);
// 调用方法
myCar.disp();
类的继承
TypeScript支持继承类,即我们可以在创建类的时候继承一个已存在的类
类继承使用关键字extends,子类除了不能继承父类的私有成员和构造函数,其它的都可以继承
TypeScript一次只能继承一个类,不支持同时继承多个类,但是TypeScript允许多重继承(A继承B,B继承C,间接地A继承B和C)
class Tire {
name: string;
constructor(name: string) {
this.name = name;
}
roll(): void {
console.log("Rolling " + this.name);
}
}
class Car extends Tire {
engine: string;
constructor(name: string, engine: string) {
super(name);
this.engine = engine;
}
disp(): void {
console.log("Engine is " + this.engine);
}
}
let myCar = new Car("Honda Civic", "V8");
继承类的方法重写
类继承后,子类可以对父类的方法重新定义,这个过程称为方法的重写
我们使用super关键字对父类直接引用,该关键字可以引用父类的属性和方法
class Tire {
name: string;
constructor(name: string) {
this.name = name;
}
disp(): void {
console.log('This is test text');
}
roll(): void {
console.log("Rolling " + this.name);
}
}
class Car extends Tire {
engine: string;
constructor(name: string, engine: string) {
super(name);
this.engine = engine;
}
disp(): void {
super.disp();
console.log("Engine is " + this.engine);
}
}
let myCar = new Car("Honda Civic", "V8");
myCar.disp();
结果:
static关键字
static关键字用于定义类的数据成员(属性和方法)为静态的,静态成员可以直接使用类名调用
class StaticMem {
static num: number;
static disp(): void {
console.log("num值为" + StaticMem.num)
}
}
StaticMem.num = 10;
StaticMem.disp();
instanceof运算符
instanceof运算符用于判断对象是否是指定的类型,如果是返回true,否则返回false
class Person {}
let obj = new Person();
let isPerson = obj instanceof Person;
console.log("obj对象是否是Person对象?", isPerson);
访问控制修饰符
使用访问控制符来保护对类、变量、方法和构造方法的访问,TypeScript支持3种不同的访问权限
- public(默认):公有,可以在任何地方被访问
- protected:受保护,可以被其自身以及其子类访问
- private:私有,只能被其定义所在的类访问
class Encapsulate {
str1:string = "hello"
private str2:string = "world"
}
var obj = new Encapsulate()
console.log(obj.str1) // 可访问
console.log(obj.str2) // 编译错误, str2 是私有的
类和接口
类可以实现接口,使用关键字implements
interface ILoan {
interest:number
}
class AgriLoan implements ILoan {
interest:number
rebate:number
constructor(interest:number,rebate:number) {
this.interest = interest
this.rebate = rebate
}
}
TypeScript对象
TypeScript类型模板
假设在JS中有下面一段代码:
const test = {
value1: 1,
value2: 2,
}
test.sayHello = function() {
console.log("Hello, world!");
}
结果:
同样的代码放到TS中就会报错:
这是因为在TypeScript对象中添加属性之前要有该属性的相关类型约束
TypeScript泛型
泛型是一种编程语言特性,允许在定义函数、类、接口等时使用占位符表示类型,而不是具体的类型
泛型标识符
- T:代表Type
- K,V:代表键和值
- E:表示数组元素
- R:表示函数返回值
- U,V:表示第二、第三个泛型类型采纳数
这些标识符是“约定俗成”的,实际上我们可以选择任何符合标识符规范的名称
泛型函数
使用泛型可以创建一个可以处理不同类型的函数
function identity<T>(arg: T): T {
return arg;
}
let res1 = identity<string>("hello");
let res2 = identity<number>(123);
泛型接口
可以使用泛型来定义接口,使接口的成员能够使用任意类型
interface Pair<T,U> {
first: T;
second: U;
}
let pair: Pair<number,string> = {
first: 1,
second: "hello"
}
泛型类
泛型也可以应用于类的实例变量和方法
class Box<T> {
private value: T;
constructor(value: T) {
this.value = value;
}
getValue(): T {
return this.value;
}
}
let stringBox = new Box<string>("hello");
泛型约束
如果你想限制泛型的类型范围,可以使用泛型约束
interface LengthWise {
length: number;
}
function logLength<T extends LengthWise>(arg: T): void {
console.log(arg.length);
}
logLength("hello"); // 5
logLength(1); // 错误
该泛型继承LengthWise,这要求该泛型上必须存在一个length属性,数字不存在,故报错
泛型与默认值
可以给泛型设置默认值,在不指定类型参数时能够使用默认值
function defaultValue<T = string>(args: T): void {
console.log(args);
}
defaultValue("Hello World");
defaultValue<number>(123);