组合模式的核心是把一组相似的对象当作一个单一的对象来处理。在JavaScript里,我们可以通过统一的接口让叶子对象和组合对象表现一致,从而用递归的方式处理树状结构。

什么是组合模式
组合模式用于构建树形结构,其中节点分为两种:叶子节点不再包含子节点,组合节点可以包含子节点。它们都实现相同的方法,例如operation(),调用组合节点时会把请求分发到它的所有子节点。
基础实现示例
下面用一个简单的文件目录例子说明怎样用JavaScript写出组合模式。叶子是文件,组合是文件夹。
// 统一接口:文件和文件夹都实现 operation 方法
class File {
constructor(name) {
this.name = name;
}
operation() {
console.log('文件: ' + this.name);
}
}
class Folder {
constructor(name) {
this.name = name;
this.children = [];
}
add(node) {
this.children.push(node);
}
operation() {
console.log('文件夹: ' + this.name);
for (let i = 0; i < this.children.length; i++) {
this.children[i].operation();
}
}
}
// 使用组合模式
const root = new Folder('根目录');
const file1 = new File('a.txt');
const subFolder = new Folder('子目录');
subFolder.add(new File('b.txt'));
root.add(file1);
root.add(subFolder);
root.operation();
关键点说明
- 叶子类和组合类实现相同的方法名,保证调用方无差别使用。
- 组合类内部维护子节点列表,并在方法中遍历调用子节点方法。
- 可以动态添加或删除节点,树形结构灵活可变。
实际应用场景
在前端开发中,组合模式常用于渲染嵌套菜单、权限树、组件树等。只要出现“整体与部分”需要一致对待的情况,都可以考虑该模式。
菜单例子
class MenuItem {
constructor(title) {
this.title = title;
}
render() {
return '<li>' + this.title + '</li>';
}
}
class Menu {
constructor(title) {
this.title = title;
this.items = [];
}
add(item) {
this.items.push(item);
}
render() {
let html = '<li>' + this.title + '<ul>';
for (let i = 0; i < this.items.length; i++) {
html += this.items[i].render();
}
html += '</ul></li>';
return html;
}
}
const menu = new Menu('系统');
menu.add(new MenuItem('设置'));
menu.add(new MenuItem('退出'));
console.log(menu.render());
小结
用JavaScript实现组合模式并不复杂,重点是抽象出公共接口,让叶子与组合对象可以被统一处理。这样能使代码更清晰,也更容易应对后续的结构变化。
JavaScript组合模式设计模式修改时间:2026-07-29 21:03:25