作用域差异
- 名字空间(Namespace):
- 名字空间的作用域是全局的(在其定义的文件内相对全局)。它主要用于将相关代码组织在一起,避免全局命名冲突。名字空间内部的声明会提升到其所在的全局作用域。例如:
namespace MathUtils {
export function add(a: number, b: number): number {
return a + b;
}
}
// 这里可以直接使用MathUtils.add
let result1 = MathUtils.add(1, 2);
- 模块(Module):
- 模块有自己独立的作用域。模块内的变量、函数等声明默认是私有的,只有通过
export
关键字导出后才能被其他模块访问。例如:
// mathUtils.ts模块
function add(a: number, b: number): number {
return a + b;
}
export { add };
// main.ts
import { add } from './mathUtils';
let result2 = add(1, 2);
对代码组织和维护的影响
- 名字空间在实际项目中的影响:
- 代码组织:适合小型项目或者需要将一些工具类代码组织在一起且不需要严格隔离的场景。例如在一个简单的Web项目中,可能有一些通用的UI工具函数,使用名字空间可以将它们组织在一起。
namespace UIUtils {
export function showMessage(message: string) {
alert(message);
}
}
- 维护:由于名字空间的全局性质,在大型项目中如果不小心可能会造成命名冲突。比如多个开发者都定义了名为
Utils
的名字空间,就可能导致意外问题。
- 模块在实际项目中的影响:
- 代码组织:更适合大型项目,模块可以将相关功能封装在一起,每个模块有明确的接口(导出的内容)。例如在一个大型的电商项目中,用户模块、商品模块等可以各自作为独立的模块,模块间通过导入导出进行交互。
// user.ts模块
class User {
constructor(public name: string) {}
}
export { User };
// main.ts
import { User } from './user';
let user = new User('John');
- 维护:模块的隔离性使得代码更易于维护和扩展。一个模块的内部实现修改不会影响其他模块,只要导出的接口不变。例如修改
user.ts
模块内部用户验证逻辑,只要 User
类的导出接口不变,其他使用该模块的地方无需修改。