TypeScript 的 class
和 ES6(JavaScript)的 class
有很多相似之处,但 TypeScript 在原生 ES6 的基础上增加了静态类型检查和一些面向对象编程的功能扩展。以下是两者的主要区别:
1. 类型系统
TypeScript 的 class
支持类型注解,而 ES6 的 class
是动态类型的。
TypeScript 示例:
class User {
name: string; // 属性类型
age: number; // 属性类型
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
greet(): string { // 方法返回值类型
return `Hello, my name is ${this.name}`;
}
}
const user = new User("Alice", 30);
// user.age = "thirty"; // ❌ 报错:类型 'string' 不能赋值给 'number'
ES6 示例:
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
return `Hello, my name is ${this.name}`;
}
}
const user = new User("Alice", 30);
user.age = "thirty"; // ✅ 不会报错
区别:
- TypeScript 在编译时会检查类型是否正确。
- ES6 无类型检查,所有类型问题都只能在运行时发现。
2. 访问修饰符
TypeScript 支持 public
、private
和 protected
修饰符,用于控制类的成员访问权限。ES6 中没有这些修饰符。
TypeScript 示例:
class User {
public name: string; // 公共成员
private age: number; // 私有成员
protected role: string; // 受保护成员
constructor(name: string, age: number, role: string) {
this.name = name;
this.age = age;
this.role = role;
}
private getAge(): number { // 私有方法
return this.age;
}
}
const user = new User("Alice", 30, "admin");
console.log(user.name); // ✅ 可以访问
// console.log(user.age); // ❌ 报错:'age' 是私有属性
// console.log(user.getAge()); // ❌ 报错:'getAge' 是私有方法
ES6 示例:
class User {
constructor(name, age, role) {
this.name = name;
this.age = age; // 没有真正的“私有”属性
this.role = role;
}
getAge() {
return this.age;
}
}
const user = new User("Alice", 30, "admin");
console.log(user.name); // ✅ 可以访问
console.log(user.age); // ✅ 仍然可以访问
区别:
- TypeScript 提供编译时的访问控制(
public
、private
、protected
)。- ES6 通过命名约定(如
_age
)模拟私有属性,但没有语言层级的限制。
3. 抽象类
TypeScript 支持 abstract
关键字来定义抽象类和抽象方法,ES6 不支持。
TypeScript 示例:
abstract class Shape {
abstract getArea(): number; // 抽象方法,子类必须实现
}
class Circle extends Shape {
constructor(public radius: number) {
super();
}
getArea(): number {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.getArea()); // 78.53981633974483
ES6 示例: ES6 中只能通过抛出错误的方式模拟抽象类:
class Shape {
getArea() {
throw new Error("This method must be implemented by subclass");
}
}
class Circle extends Shape {
constructor(radius) {
super();
this.radius = radius;
}
getArea() {
return Math.PI * this.radius ** 2;
}
}
const circle = new Circle(5);
console.log(circle.getArea()); // 78.53981633974483
区别:
- TypeScript 原生支持抽象类和抽象方法,编译时检查。
- ES6 需要通过运行时抛错来模拟。
4. 接口支持
TypeScript 支持 interface
,可以用来定义类的结构并强制实现,而 ES6 没有接口的概念。
TypeScript 示例:
interface Printable {
print(): void;
}
class Document implements Printable {
print() {
console.log("Printing document...");
}
}
const doc = new Document();
doc.print(); // Printing document...
ES6 示例: 在 ES6 中,接口功能需要通过注释和开发约定来模拟:
class Document {
print() {
console.log("Printing document...");
}
}
const doc = new Document();
doc.print(); // Printing document...
区别:
- TypeScript 提供接口来定义类的契约,并在编译时强制实现。
- ES6 缺少接口的功能,需要通过约定实现。
5. 静态检查 vs 动态行为
TypeScript 的 class
更注重编译时的静态检查,而 ES6 的 class
是纯粹的运行时结构。
TypeScript 示例:
class User {
name: string;
constructor(name: string) {
this.name = name;
}
}
const user: User = new User("Alice");
// user.age = 30; // ❌ 报错:属性 'age' 不存在
ES6 示例:
class User {
constructor(name) {
this.name = name;
}
}
const user = new User("Alice");
user.age = 30; // ✅ 没有报错,动态添加属性
区别:
- TypeScript 在编译时就能发现类型错误。
- ES6 在运行时处理错误。
总结
特性 | TypeScript 的 class | ES6 的 class |
---|---|---|
类型系统 | 静态类型,编译时检查 | 动态类型,运行时检查 |
访问修饰符 | 支持 public 、private 、protected | 不支持 |
抽象类 | 支持 abstract | 不支持 |
接口支持 | 支持 interface 定义和实现 | 不支持 |
运行时功能 | 生成的代码与 ES6 类似,但提供类型检查 | 只提供运行时功能 |
多态和继承 | 支持继承、接口实现(implements )和类型安全 | 支持继承 |
用途 | 适合复杂系统,强调类型安全,支持静态检查 | 适合简单场景,动态灵活 |
TypeScript 的 class
在保持 ES6 语法的基础上,为开发者提供了类型检查和更强的面向对象编程支持。