Skip to content
On this page

参考:https://www.w3cschool.cn/zobyhd/tqlv9ozt.html

JavaScript设计模式面试题汇总

1、单例模式

单例模式又称单体模式,保证一个类仅有一个实例,并提供一个全局访问点。

实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这样就确保了一个类只有一个实例对象。例如: jQuery

js
var Singleton = (function () {
  var instance;

  function createInstance() {
    var object = new Object("I am the instance");
    return object;
  }

  return {
    getInstance: function () {
      if (!instance) {
        instance = createInstance();
      }
      return instance;
    }
  };
})();

var instance1 = Singleton.getInstance();
var instance2 = Singleton.getInstance();

console.log(instance1 === instance2); // 输出 true,说明两个实例是同一个对象

2、工厂模式

工厂模式是一种创建对象的设计模式,它抽象了创建具体对象的过程。在工厂模式中,创建对象的逻辑被封装在一个函数中,这个函数就被事务一个工厂。

js
// 定义一个动物类
function Animal(name) {
  this.name = name;
}
Animal.prototype.speak = function () {
  console.log(this.name + " makes a noise.");
};

// 定义狗类和猫类
function Dog(name) {
  Animal.call(this, name);
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.speak = function () {
  console.log(this.name + " barks.");
};

function Cat(name) {
  Animal.call(this, name);
}
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;
Cat.prototype.speak = function () {
  console.log(this.name + " meows.");
};

// 定义一个动物工厂
function AnimalFactory() {}
AnimalFactory.prototype.createAnimal = function (type, name) {
  if (type === "Dog") {
    return new Dog(name);
  } else if (type === "Cat") {
    return new Cat(name);
  } else {
    return new Animal(name);
  }
};

// 使用工厂模式创建动物对象
var animalFactory = new AnimalFactory();
var dog = animalFactory.createAnimal("Dog", "Tommy");
dog.speak(); // 输出 "Tommy barks."
var cat = animalFactory.createAnimal("Cat", "Kitty");
cat.speak(); // 输出 "Kitty meows."

3、策略模式

策略模式是一种它定义了一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换

js
// 定义策略对象
var strategies = {
  "A": function () {
    return "Strategy A";
  },
  "B": function () {
    return "Strategy B";
  },
  "C": function () {
    return "Strategy C";
  }
};

// 定义上下文对象
function Context(strategy) {
  this.executeStrategy = function () {
    return strategies[strategy]();
  };
}

// 使用策略模式
var context = new Context("A");
console.log(context.executeStrategy()); // 输出 "Strategy A"

context = new Context("B");
console.log(context.executeStrategy()); // 输出 "Strategy B"

context = new Context("C");
console.log(context.executeStrategy()); // 输出 "Strategy C"

4、代理模式

代理模式是一种结构型设计模式,它通过引入一个代理对象来控制对原始对象的访问,在不改变原始对象的基础上进行一些额外操作

js
// 定义目标对象
var target = {
  name: "John",
  age: 30
};

// 定义处理程序对象
var handler = {
    get: function (target, property) {
      if (property in target) {
        return target[property];
      } else {
        return "Property not found";
      }
    },
    set: function (target, property, value) {
      if (property === "age" && typeof value !== "number") {
        throw new Error("Age must be a number");
      }
      target[property] = value;
    }
};

// 创建代理对象
var proxy = new Proxy(target, handler);

// 访问代理对象的属性
console.log(proxy.name); // 输出 "John"
console.log(proxy.age); // 输出 30
console.log(proxy.gender); // 输出 "Property not found"

// 修改代理对象的属性
proxy.age = 35; // 正常修改
console.log(proxy.age); // 输出 35
proxy.age = "40"; // 抛出错误 "Age must be a number"

5、中介者模式

中介者模式是一种行为设计模式,它允许对象之间通过一个中介对象进行通信,从而减少对象之间的依赖关系

js
// 定义中介者对象
function Mediator() {
  this.events = {};
}
Mediator.prototype.subscribe = function (event, callback) {
  if (!this.events[event]) {
    this.events[event] = [];
  }
  this.events[event].push(callback);
};
Mediator.prototype.publish = function (event, data) {
  if (this.events[event]) {
    this.events[event].forEach(function (callback) {
      callback(data);
    });
  }
};

// 定义订阅者对象
function Subscriber(name) {
  this.name = name;
}
Subscriber.prototype.receive = function (data) {
  console.log(this.name + " received: " + data);
};

// 创建中介者实例
var mediator = new Mediator();

// 创建订阅者实例
var subscriber1 = new Subscriber("Subscriber 1");
var subscriber2 = new Subscriber("Subscriber 2");
var subscriber3 = new Subscriber("Subscriber 3");

// 订阅事件
mediator.subscribe("event1", subscriber1.receive);
mediator.subscribe("event1", subscriber2.receive);
mediator.subscribe("event2", subscriber3.receive);

// 发布事件
mediator.publish("event1", "Hello, World!"); // 输出 "Subscriber 1 received: Hello, World!" 和 "Subscriber 2 received: Hello, World!"
mediator.publish("event2", "Goodbye, World!"); // 输出 "Subscriber 3 received: Goodbye, World!"

6、装饰器模式

装饰模式是一种结构型设计模式,它允许在不修改对象代码的情况下向对象添加新功能。

js
// 定义原始对象
function OriginalObject() {
  this.name = "John";
}
OriginalObject.prototype.sayHello = function () {
  console.log("Hello, my name is " + this.name);
};

// 定义装饰器函数
function Decorator(obj) {
  this.obj = obj;
}
Decorator.prototype.sayHello = function () {
  this.obj.sayHello();
  console.log("And I am decorated!");
};

// 使用装饰器模式
var originalObj = new OriginalObject();
var decoratedObj = new Decorator(originalObj);

originalObj.sayHello(); // 输出 "Hello, my name is John"
decoratedObj.sayHello(); // 输出 "Hello, my name is John" 和 "And I am decorated!"

7、构造器模式

构造器模式是一种创建型设计模式,它使用特殊的构造函数来创建对象。

js
// 定义构造器函数
function Person(name, age) {
  this.name = name;
  this.age = age;
}
Person.prototype.sayHello = function () {
  console.log("Hello, my name is " + this.name + " and I am " + this.age + " years old.");
};

// 使用构造器模式创建对象
var person1 = new Person("John", 30);
var person2 = new Person("Jane", 25);

person1.sayHello(); // 输出 "Hello, my name is John and I am 30 years old."
person2.sayHello(); // 输出 "Hello, my name is Jane and I am 25 years old."

8、模块化模式

模块化模式是一种将代码分割成独立的、可重用的模块的设计模式。

js
// 定义模块1
var module1 = (function () {
  var privateVar = "I am private";
  function privateFunction() {
    console.log(privateVar);
  }
  return {
    publicFunction: function () {
      privateFunction();
    }
  };
})();

// 定义模块2
var module2 = (function () {
  var privateVar = "I am another private variable";
  function privateFunction() {
    console.log(privateVar);
  }
  return {
    publicFunction: function () {
      privateFunction();
    }
  };
})();

// 使用模块
module1.publicFunction(); // 输出 "I am private"
module2.publicFunction(); // 输出 "I am another private variable"

9、原型模式

原型模式是一种创建型设计模式,它通过复制现有对象来创建新对象。

js
// 定义原型对象
function Prototype() {
  this.name = "John";
}
Prototype.prototype.sayHello = function () {
  console.log("Hello, my name is " + this.name);
};

// 使用原型模式创建对象
var obj1 = new Prototype();
var obj2 = Object.create(obj1);

obj1.sayHello(); // 输出 "Hello, my name is John"
obj2.sayHello(); // 输出 "Hello, my name is John"

10、mixin模式

Mixin模式是一种将多个类的功能合并到一个类中的设计模式。在JavaScript中,可以使用对象和函数来实现Mixin模式。

js
// 定义Mixin1
var Mixin1 = {
  sayHello: function () {
    console.log("Hello from Mixin1");
  }
};
// 定义Mixin2
var Mixin2 = {
  sayGoodbye: function () {
    console.log("Goodbye from Mixin2");
  }
};

// 定义目标类
function Target() {}
// 使用Mixin1和Mixin2扩展目标类
Object.assign(Target.prototype, Mixin1, Mixin2);

// 创建目标类的实例并调用方法
var target = new Target();
target.sayHello(); // 输出 "Hello from Mixin1"
target.sayGoodbye(); // 输出 "Goodbye from Mixin2"

11、观察者模式

观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

js
// 定义主题(Subject)
function Subject() {
  this.observers = []; // 存储观察者列表
}
Subject.prototype = {
  // 添加观察者
  subscribe: function (observer) {
    this.observers.push(observer);
  },
  // 移除观察者
  unsubscribe: function (observer) {
    var index = this.observers.indexOf(observer);
    if (index > -1) {
      this.observers.splice(index, 1);
    }
  },
  // 通知所有观察者
  notify: function () {
    for (var i = 0; i < this.observers.length; i++) {
      this.observers[i].update();
    }
  }
};

// 定义观察者(Observer)
function Observer(name) {
  this.name = name;
}
Observer.prototype = {
  // 更新方法
  update: function () {
    console.log(this.name + " has been notified!");
  }
};

// 使用观察者模式
var subject = new Subject(); // 创建主题
var observer1 = new Observer("Observer 1"); // 创建观察者1
var observer2 = new Observer("Observer 2"); // 创建观察者2

subject.subscribe(observer1); // 订阅观察者1
subject.subscribe(observer2); // 订阅观察者2

subject.notify(); // 通知所有观察者

12、命令模式

命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求、队列或日志请求来参数化其他对象。

js
// 定义命令对象
function Command(execute, undo, value) {
  this.execute = execute;
  this.undo = undo;
  this.value = value;
}

// 定义执行器对象
var Executor = {
  execute: function (command) {
    command.execute(command.value);
  },
  undo: function (command) {
    command.undo(command.value);
  }
};

// 定义具体命令对象
var AddCommand = function (value) {
  return new Command(function (value) {
    console.log("Adding " + value);
  }, function (value) {
    console.log("Undo adding " + value);
  }, value);
};

var SubtractCommand = function (value) {
  return new Command(function (value) {
    console.log("Subtracting " + value);
  }, function (value) {
    console.log("Undo subtracting " + value);
  }, value);
};

// 使用命令模式
var addCommand = AddCommand(5);
Executor.execute(addCommand); // 输出 "Adding 5"
Executor.undo(addCommand); // 输出 "Undo adding 5"

var subtractCommand = SubtractCommand(3);
Executor.execute(subtractCommand); // 输出 "Subtracting 3"
Executor.undo(subtractCommand); // 输出 "Undo subtracting 3"

13、外观模式

外观模式是一种结构型设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更加容易使用。

js
// 定义子系统1
function Subsystem1() {
  this.operation1 = function () {
    console.log("Subsystem1 operation1");
  };
}

// 定义子系统2
function Subsystem2() {
  this.operation2 = function () {
    console.log("Subsystem2 operation2");
  };
}

// 定义外观对象
function Facade() {
  this.subsystem1 = new Subsystem1();
  this.subsystem2 = new Subsystem2();
}

Facade.prototype.operation = function () {
  this.subsystem1.operation1();
  this.subsystem2.operation2();
};

// 使用外观模式
var facade = new Facade();
facade.operation(); // 输出 "Subsystem1 operation1" 和 "Subsystem2 operation2"

14、暴露模块模式

暴露模块模式是一种设计模式,它允许一个模块公开一些方法或属性,而隐藏其他方法和属性。

js
// 定义模块
var myModule = (function () {
  // 私有变量和方法
  var privateVar = "I am private";
  function privateMethod() {
    console.log("This is a private method");
  }

  // 暴露给外部的对象
  return {
    publicVar: "I am public",
    publicMethod: function () {
      console.log("This is a public method");
      privateMethod(); // 可以访问私有方法
    }
  };
})();

// 使用模块
console.log(myModule.publicVar); // 输出 "I am public"
myModule.publicMethod(); // 输出 "This is a public method" 和 "This is a private method"

15、享元(Flyweight)模式

享元模式是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。

js
// 定义享元工厂
function FlyweightFactory() {
  var flyweights = {};

  function getFlyweight(key) {
    if (!flyweights[key]) {
      flyweights[key] = new Flyweight(key);
    }
    return flyweights[key];
  }

  function Flyweight(key) {
    this.key = key;
  }

  return {
    getFlyweight: getFlyweight
  };
}

// 使用享元模式
var factory = new FlyweightFactory();
var flyweight1 = factory.getFlyweight("A");
var flyweight2 = factory.getFlyweight("B");
var flyweight3 = factory.getFlyweight("A");

console.log(flyweight1 === flyweight3); // 输出 true
console.log(flyweight1 === flyweight2); // 输出 false

16、适配器模式

适配器模式是一种结构型设计模式,它允许不兼容的对象协同工作。

js
// 定义旧接口
function OldInterface() {
  this.oldMethod = function () {
    console.log("Old interface method");
  };
}

// 定义新接口
function NewInterface() {
  this.newMethod = function () {
    console.log("New interface method");
  };
}

// 定义适配器
function Adapter(oldInterface) {
  this.newInterface = new NewInterface();
  this.oldInterface = oldInterface;
}

Adapter.prototype.request = function () {
  this.oldInterface.oldMethod();
  this.newInterface.newMethod();
};

// 使用适配器
var oldInterface = new OldInterface();
var adapter = new Adapter(oldInterface);
adapter.request(); // 输出 "Old interface method" 和 "New interface method"

17、发布订阅者模式

发布订阅者模式是一种行为型设计模式,它允许对象之间进行松耦合的通信。

js
// 定义事件管理器
function EventManager() {
  this.events = {};
}
EventManager.prototype.subscribe = function (eventName, callback) {
  if (!this.events[eventName]) {
    this.events[eventName] = [];
  }
  this.events[eventName].push(callback);
};
EventManager.prototype.publish = function (eventName, data) {
  if (this.events[eventName]) {
    this.events[eventName].forEach(function (callback) {
      callback(data);
    });
  }
};

// 使用事件管理器
var eventManager = new EventManager();
// 订阅事件
eventManager.subscribe("myEvent", function (data) {
  console.log("Subscriber 1 received: " + data);
});
eventManager.subscribe("myEvent", function (data) {
  console.log("Subscriber 2 received: " + data);
});

// 发布事件
eventManager.publish("myEvent", "Hello, world!"); // 输出 "Subscriber 1 received: Hello, world!" 和 "Subscriber 2 received: Hello, world!"

Released under the MIT License.