面试题答案
一键面试主要区别
- 作用域
- 名字空间:用于组织代码,其作用域是全局的,通过将相关代码放在同一个名字空间内,避免全局变量冲突。例如:
namespace Utils { export function add(a: number, b: number): number { return a + b; } }
- 模块:每个模块都有自己独立的作用域,模块内的变量、函数等默认是私有的,只有通过
export
关键字导出才能在外部访问。例如:
// module.ts const privateVariable = 'This is private'; export function publicFunction(): string { return 'Accessed from outside'; }
- 文件组织和依赖
- 名字空间:通常在单个文件内定义多个名字空间,或者多个文件通过
/// <reference>
指令关联。例如:
// file1.ts namespace App { export class User { name: string; constructor(name: string) { this.name = name; } } } // file2.ts /// <reference path="file1.ts" /> namespace App { export function greet(user: User) { return `Hello, ${user.name}`; } }
- 模块:每个模块是一个独立的文件,模块之间通过
import
和export
进行依赖管理。例如:
// user.ts export class User { name: string; constructor(name: string) { this.name = name; } } // greet.ts import { User } from './user'; export function greet(user: User) { return `Hello, ${user.name}`; }
- 名字空间:通常在单个文件内定义多个名字空间,或者多个文件通过
- 编译和运行时行为
- 名字空间:编译后会将所有相关代码合并到全局作用域中,适合简单项目,无需额外的模块加载器。
- 模块:编译后每个模块保持独立,在运行时需要模块加载器(如 Node.js 的
CommonJS
或浏览器环境的ES6 模块加载
)来按需加载模块。
优先使用场景
- 优先使用名字空间的场景
- 简单项目或小型库:当项目规模较小,代码结构相对简单,不需要复杂的模块依赖管理时。例如,开发一个简单的网页工具,只包含一些辅助函数和类。假设要开发一个简单的表单验证工具:
namespace FormValidator { export function validateEmail(email: string): boolean { const re = /\S+@\S+\.\S+/; return re.test(email); } export function validatePassword(password: string): boolean { return password.length >= 6; } } // 在 HTML 页面中使用 const email = document.getElementById('email') as HTMLInputElement; const password = document.getElementById('password') as HTMLInputElement; const submit = document.getElementById('submit'); submit?.addEventListener('click', () => { const emailValid = FormValidator.validateEmail(email.value); const passwordValid = FormValidator.validatePassword(password.value); if (emailValid && passwordValid) { alert('Form is valid'); } else { alert('Form is invalid'); } });
- 优先使用模块的场景
- 大型项目和复杂应用:在大型项目中,代码结构复杂,有大量的模块需要独立开发、维护和复用。例如,开发一个大型的电商应用,有用户模块、商品模块、订单模块等。
- 以用户模块为例:
- user.ts
export class User { id: number; name: string; constructor(id: number, name: string) { this.id = id; this.name = name; } } export function getUserById(id: number): User { // 模拟从数据库获取用户 return new User(id, 'User' + id); }
- order.ts
import { User } from './user'; export class Order { userId: number; items: string[]; constructor(userId: number, items: string[]) { this.userId = userId; this.items = items; } getUser(): User { return getUserById(this.userId); } }
- 模块之间的清晰依赖关系使得代码更易于维护和扩展,并且便于在不同的环境(如 Node.js 服务器端和浏览器客户端)中使用。