前言本系列文章主要根据《JavaScript设计模式与开发实践》整理而来,其中会加入了一些自己的思考。希望对大家有所帮助。文章系列js设计模式–单例模式js设计模式–策略模式js设计模式–代理模式js设计模式–迭代器模式js设计模式–发布订阅模式概念命令模式中的命令(command)指的是一个执行某些特定事情的指令。场景有时候需要向某些对象发送请求,但是并不知道请求的接收 者是谁,也不知道被请求的操作是什么。如快餐店点餐,我们不需要知道厨师是谁,我们只需要把订单交给服务员优缺点请求发送者和请求接收者能够消除彼此之间的耦合关系例子按钮点击简单的实现<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <button id=“button1”>点击按钮1</button> <script> var button1 = document.getElementById(‘button1’) button1.onclick = function () { console.log(‘刷新菜单目录’); } </script></body></html>如果这个点击事件实现很复杂,需要多人合作完成,那我们不得不深入到button1.onclick内部去修改代码,违背了开放封闭原则命令模式实现<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <button id=“button1”>点击按钮1</button> <script> var button1 = document.getElementById(‘button1’) var setCommand = function (button, command) { button.onclick = function () { command.execute(); } }; var MenuBar = { refresh: function () { console.log(‘刷新菜单目录’); } }; var RefreshMenuBarCommand = function (receiver) { this.receiver = receiver; }; RefreshMenuBarCommand.prototype.execute = function () { this.receiver.refresh(); }; var refreshMenuBarCommand = new RefreshMenuBarCommand(MenuBar); setCommand(button1, refreshMenuBarCommand); </script></body></html>JavaScript 作为将函数作为一等对象的语言,跟策略模式一样,命令模式也早已融入到了 JavaScript 语言之中。js中的命令模式<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <button id=“button1”>点击按钮1</button> <script> var button1 = document.getElementById(‘button1’) var setCommand = function (button, fn) { button.onclick = fn }; var MenuBar = { refresh: function () { console.log(‘刷新菜单目录’); } }; setCommand(button1, MenuBar.refresh) </script></body></html>设置背景色的例子撤销命令我们现在来实现一个撤销操作的例子:界面上有四个按钮,三个可以设置不同的背景色,undo按钮可以撤销上一次的操作<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <div id=“div” style=“height: 100px;width: 100px;background-color: blue”></div> <button id=“button1”>red</button> <button id=“button2”>black</button> <button id=“button3”>yellow</button> <button id=“undo”>undo</button> <script> var button1 = document.getElementById(‘button1’) var button2 = document.getElementById(‘button2’) var button3 = document.getElementById(‘button3’) var undo = document.getElementById(‘undo’) var div = document.getElementById(‘div’) var cacheColor = [] var setCommand = function (button, fn) { button.onclick = fn }; var commond = { cache: [], receiver: null, execute(newBgColor) { this.cache.push(this.receiver.style.backgroundColor) this.receiver.style.backgroundColor = newBgColor }, undo() { var oldBgColor = this.cache.pop() this.receiver.style.backgroundColor = oldBgColor }, setReceiver(target) { this.receiver = target } } commond.setReceiver(div) button1.onclick = function () { commond.execute(‘red’) } button2.onclick = function () { commond.execute(‘black’) } button3.onclick = function () { commond.execute(‘yellow’) } undo.onclick = function () { commond.undo() } </script></body></html>重做操作这里我们增加一个redo按钮,以恢复之前的操作,需要一个currentIndex来记录当前的索引<!DOCTYPE html><html lang=“en”><head> <meta charset=“UTF-8”> <meta name=“viewport” content=“width=device-width, initial-scale=1.0”> <meta http-equiv=“X-UA-Compatible” content=“ie=edge”> <title>Document</title></head><body> <div id=“div” style=“height: 100px;width: 100px;background-color: blue”></div> <button id=“button1”>red</button> <button id=“button2”>black</button> <button id=“button3”>yellow</button> <button id=“undo”>undo</button> <button id=“redo”>redo</button> <script> var button1 = document.getElementById(‘button1’) var button2 = document.getElementById(‘button2’) var button3 = document.getElementById(‘button3’) var undo = document.getElementById(‘undo’) var div = document.getElementById(‘div’) var commond = { cache: [], currentIndex: 0, receiver: null, execute(newBgColor) { this.receiver.style.backgroundColor = newBgColor this.currentIndex++ this.cache.push(newBgColor) console.log(’execute:’, this.cache, this.currentIndex) }, undo() { if (this.currentIndex <= 0) return var oldBgColor = this.cache[–this.currentIndex] this.receiver.style.backgroundColor = oldBgColor console.log(‘undo:’, this.cache, this.currentIndex) }, redo() { if (this.currentIndex >= this.cache.length - 1) return var preBgColor = this.cache[this.currentIndex + 1] this.currentIndex++ this.receiver.style.backgroundColor = preBgColor console.log(‘redo:’, this.cache, this.currentIndex) }, setReceiver(target) { this.receiver = target this.cache.push(this.receiver.style.backgroundColor) console.log(‘setReceiver:’, this.cache, this.currentIndex) } } commond.setReceiver(div) button1.onclick = function () { commond.execute(‘red’) } button2.onclick = function () { commond.execute(‘black’) } button3.onclick = function () { commond.execute(‘yellow’) } undo.onclick = function () { commond.undo() } redo.onclick = function () { commond.redo() } </script></body></html>