本系列文章主要根據《JavaScript設計模式與開發實踐》整理而來,其中會加入了一些本身的思考。但願對你們有所幫助。html
js設計模式--單例模式segmentfault
js設計模式--策略模式設計模式
js設計模式--發佈訂閱模式this
命令模式中的命令(command)指的是一個執行某些特定事情的指令。prototype
有時候須要向某些對象發送請求,可是並不知道請求的接收 者是誰,也不知道被請求的操做是什麼。
如快餐店點餐,咱們不須要知道廚師是誰,咱們只須要把訂單交給服務員設計
請求發送者和請求接收者可以消除彼此之間的耦合關係代理
<!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內部去修改代碼,違背了開放封閉原則code
<!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 語言之中。
<!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>