参考:https://www.w3cschool.cn/zobyhd/tqlv9ozt.html
JavaScript设计模式面试题汇总
1、单例模式
单例模式又称单体模式,保证一个类仅有一个实例,并提供一个全局访问点。
实现的方法为先判断实例存在与否,如果存在则直接返回,如果不存在就创建了再返回,这样就确保了一个类只有一个实例对象。例如: jQuery
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、工厂模式
工厂模式是一种创建对象的设计模式,它抽象了创建具体对象的过程。在工厂模式中,创建对象的逻辑被封装在一个函数中,这个函数就被事务一个工厂。
// 定义一个动物类
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、策略模式
策略模式是一种它定义了一系列算法,并将每个算法封装在一个具有共同接口的独立类中,使得它们可以相互替换。
// 定义策略对象
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、代理模式
代理模式是一种结构型设计模式,它通过引入一个代理对象来控制对原始对象的访问,在不改变原始对象的基础上进行一些额外操作。
// 定义目标对象
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、中介者模式
中介者模式是一种行为设计模式,它允许对象之间通过一个中介对象进行通信,从而减少对象之间的依赖关系。
// 定义中介者对象
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、装饰器模式
装饰模式是一种结构型设计模式,它允许在不修改对象代码的情况下向对象添加新功能。
// 定义原始对象
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、构造器模式
构造器模式是一种创建型设计模式,它使用特殊的构造函数来创建对象。
// 定义构造器函数
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、模块化模式
模块化模式是一种将代码分割成独立的、可重用的模块的设计模式。
// 定义模块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、原型模式
原型模式是一种创建型设计模式,它通过复制现有对象来创建新对象。
// 定义原型对象
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模式。
// 定义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、观察者模式
观察者模式是一种行为设计模式,它定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。
// 定义主题(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、命令模式
命令模式是一种行为设计模式,它将请求封装为一个对象,从而使你可以使用不同的请求、队列或日志请求来参数化其他对象。
// 定义命令对象
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、外观模式
外观模式是一种结构型设计模式,它为子系统中的一组接口提供一个统一的高层接口,使得子系统更加容易使用。
// 定义子系统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、暴露模块模式
暴露模块模式是一种设计模式,它允许一个模块公开一些方法或属性,而隐藏其他方法和属性。
// 定义模块
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)模式
享元模式是一种结构型设计模式,它通过共享对象来减少内存使用和提高性能。
// 定义享元工厂
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、适配器模式
适配器模式是一种结构型设计模式,它允许不兼容的对象协同工作。
// 定义旧接口
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、发布订阅者模式
发布订阅者模式是一种行为型设计模式,它允许对象之间进行松耦合的通信。
// 定义事件管理器
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!"
前端知识库