面试题答案
一键面试策略一:将共享部分提取到独立模块
- 思路:找出A和B中互相依赖的共享部分,将其提取到一个新的独立模块C中。这样A和B都依赖C,避免了A和B之间的直接循环依赖。
- 代码示例:
- 模块C(共享模块):
// shared.js
const sharedFunction = () => {
return "This is a shared function";
};
const sharedValue = "Shared value";
export { sharedFunction, sharedValue };
- **模块A**:
// moduleA.js
import { sharedFunction, sharedValue } from './shared.js';
const moduleAFunction = () => {
console.log(sharedFunction());
return "Module A function";
};
export { moduleAFunction };
- **模块B**:
// moduleB.js
import { sharedFunction, sharedValue } from './shared.js';
const moduleBFunction = () => {
console.log(sharedValue);
return "Module B function";
};
export { moduleBFunction };
策略二:使用动态导入(ES2020+)
- 思路:在需要使用依赖模块的地方,通过
import()
动态导入,而不是静态导入。这样在运行时才会解析依赖,避免早期循环依赖问题。 - 代码示例:
- 模块A:
// moduleA.js
const moduleAFunction = async () => {
const { moduleBFunction } = await import('./moduleB.js');
console.log(await moduleBFunction());
return "Module A function";
};
export { moduleAFunction };
- **模块B**:
// moduleB.js
const moduleBFunction = async () => {
const { moduleAFunction } = await import('./moduleA.js');
console.log(await moduleAFunction());
return "Module B function";
};
export { moduleBFunction };
请注意,在实际使用动态导入时,需要处理好异步操作和可能出现的错误情况。
策略三:重新设计模块结构
- 思路:重新审视模块A和B的功能,对其进行合理拆分和重组,避免循环依赖。比如可以按照功能的不同层次或者不同业务逻辑进行重新划分模块。
- 代码示例:
假设最初模块A负责用户登录和获取用户信息,模块B负责用户权限验证且依赖获取用户信息功能,而模块A又依赖权限验证来判断登录是否成功。
- 新模块划分:
- 模块UserLogin:负责用户登录逻辑。
- 新模块划分:
// userLogin.js
const userLogin = () => {
// 登录逻辑
return "User logged in";
};
export { userLogin };
- **模块UserInfo**:负责获取用户信息。
// userInfo.js
const getUserInfo = () => {
// 获取用户信息逻辑
return { name: "John", age: 30 };
};
export { getUserInfo };
- **模块UserPermission**:负责用户权限验证。
// userPermission.js
import { getUserInfo } from './userInfo.js';
const checkPermission = () => {
const user = getUserInfo();
// 根据用户信息判断权限逻辑
return user.age > 18? "Allowed" : "Not allowed";
};
export { checkPermission };
- **新的模块A(整合登录和权限验证)**:
// newModuleA.js
import { userLogin } from './userLogin.js';
import { checkPermission } from './userPermission.js';
const newModuleAFunction = async () => {
const loginResult = userLogin();
const permissionResult = await checkPermission();
return `${loginResult}, ${permissionResult}`;
};
export { newModuleAFunction };
通过这种重新设计,避免了循环依赖,使模块结构更加清晰合理。