最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript設(shè)計(jì)模式之命令模式

 更新時(shí)間:2022年01月15日 16:58:58   作者:石頭山_S  
這篇文章主要為大家介紹了javascript命令模式,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助

一. 認(rèn)識(shí)命令模式

所謂命令,也就是指執(zhí)行某些特定事情的指令,就拿喝水的例子來(lái)說(shuō),喝水執(zhí)行的指令就是將水倒在杯子里,然后端起杯子送入口中,這就是一條命令,無(wú)論誰(shuí)喝水都是這個(gè)步驟,我們不關(guān)心是誰(shuí)端起了杯子,也不關(guān)心杯子中的水到底是水還是其他東西。我們只關(guān)心這個(gè)過(guò)程,將水倒在杯子中,然后端起杯子送入口中,最后誰(shuí)喝掉了,喝掉的是飲料還是水不重要。

大家可能聽(tīng)的有點(diǎn)混,而命令模式最常見(jiàn)的應(yīng)用場(chǎng)景就是:有時(shí)候需要向某些對(duì)象發(fā)送請(qǐng)求,但是并不知道請(qǐng)求的接收者是誰(shuí),也不知道被請(qǐng)求的操作是什么。此時(shí)我們用一種松耦合的方式來(lái)設(shè)計(jì)程序,使得請(qǐng)求發(fā)送者和接收者能夠消除彼此間的耦合關(guān)系。

二. 代碼實(shí)現(xiàn)-實(shí)際應(yīng)用場(chǎng)景

在實(shí)際開(kāi)發(fā)中團(tuán)隊(duì)協(xié)作是最重要的環(huán)節(jié),假如兩個(gè)人分別得到兩個(gè)不同的任務(wù),一個(gè)人負(fù)責(zé)頁(yè)面中所有的 button 按鈕的美化,另一個(gè)人負(fù)責(zé)實(shí)現(xiàn)這些 button 的邏輯,我們?cè)趯?xiě) button 邏輯時(shí)不知道該 button 最終綁定的是頁(yè)面中的哪一個(gè)按鈕,也不知道具體點(diǎn)擊該按鈕會(huì)發(fā)生什么,此時(shí)我們用命令模式來(lái)設(shè)計(jì),來(lái)解開(kāi)按鈕和負(fù)責(zé)具體行為對(duì)象間的耦合,代碼如下所示。

    <script>
        let btns = document.querySelectorAll('button');
        // 寫(xiě)一個(gè)刷新命令
        let refreshCommand = {
            execute () {
                console.log("刷新頁(yè)面");
            }
        }
        // 寫(xiě)一個(gè)登錄按鈕命令
        let loginCommand = {
            execute () {
                console.log("執(zhí)行登錄操作");
            }
        }
        let setCommand = function( button, command) {
            button.onclick = function() {
                command.execute();
            }
        }
        // 假如第三個(gè)按鈕用來(lái)負(fù)責(zé)刷新頁(yè)面,第五個(gè)用來(lái)負(fù)責(zé)登錄操作
        setCommand( btns[2], refreshCommand);
        setCommand( btns[4], loginCommand);  

分析:我們將點(diǎn)擊按鈕后可能會(huì)發(fā)生的事件分別封裝起來(lái),它們中各自有自己的 execute 函數(shù),我們將安裝按鈕功能的函數(shù)封裝到了 setCommand 中,最后根據(jù)需求對(duì)應(yīng)安裝各個(gè)按鈕的功能便可。

三. 命令模式的撤銷(xiāo)操作

下達(dá)一個(gè)命令后,我們可能不需要了,想回到下達(dá)命令之前的狀態(tài),就需要用到撤銷(xiāo)操作,撤銷(xiāo)操作的實(shí)現(xiàn)一般是給命令對(duì)象增加一個(gè) undo 或者 unexecute 方法,在其中執(zhí)行 execute 的反向操作。

// 假如寫(xiě)一個(gè)人物向左移的命令
let moveLeftCommand = {
    execute() {
        console.log("人物向左移動(dòng)");
}
    undo (){
        console.log("人物向又移動(dòng)");
}
}

這種是簡(jiǎn)單的邏輯實(shí)現(xiàn),假如有些撤銷(xiāo)行為無(wú)法用執(zhí)行他的反向操作來(lái)實(shí)現(xiàn),那我們應(yīng)該怎么辦呢?

帶著這個(gè)問(wèn)題我們學(xué)習(xí)一種新的達(dá)到撤銷(xiāo)的方式,我們用一個(gè)棧來(lái)記錄每一步命令,想要撤銷(xiāo),我們只需要重頭開(kāi)始,從棧中拿出命令來(lái)分別執(zhí)行,將最后一次命令刪除即可。如果不刪除最后一次命令依次執(zhí)行,我們又實(shí)現(xiàn)了一個(gè)新的功能,重播。

這是一個(gè)通過(guò) WASD 來(lái)控制小球移動(dòng)的代碼實(shí)現(xiàn),我們每次按下一個(gè)有效命令時(shí),便會(huì)將該命令推入 commandStack 中來(lái)記錄小球的變化,當(dāng)點(diǎn)擊重播時(shí)小球會(huì)按照之前同樣的軌跡運(yùn)動(dòng)。

        let role = document.getElementById('role');
        
        let move = {
            dom: role,
            leftt:0,
            top: 0,
            up() {
                console.log("向上");
                this.top -= 10;
                this.dom.style.top = this.top + 'px';
            },
            down(){
                console.log("向下");
                this.top += 10;
                this.dom.style.top = this.top + 'px';
            },
            left() {
                console.log("向左");
                this.leftt -= 10;
                this.dom.style.left = this.leftt + 'px';
            },
            right() {
                console.log("向右");
                this.leftt += 10;
                this.dom.style.left = this.leftt + 'px';
            }
        }
        commands = {
            "119": "up",      // W
            "115": "down",    // S
            "97": "left",    // A
            "100": "right"     // D
        };
        commandStack = []; // 保存命令的堆棧
        let setCommand = function (receiver, state) {
            return function() {
                receiver[state]();
            }
        }
        document.addEventListener('keypress', (e) => {
            let code = e.charCode;
            if(!commands[code]) {
                return ;
            }
            let command = setCommand(move, commands[code]);
            if( command ) {
                command();
                commandStack.push( command );
            }
        })
        // 設(shè)置重播按鈕
        document.getElementById('replay').onclick = function() {
            let command;
            while(command = commandStack.shift()) {
                command();
            }
        }

四. 宏命令

宏命令就是一組命令的集合,通過(guò)執(zhí)行宏命令可以一次執(zhí)行一批命令。

通俗來(lái)說(shuō)就是,有一件事你需要重復(fù)做,并且做這件事的每一步都是固定不變的,那么我們可以將做這件事情的所有步驟打包起來(lái),只需要啟動(dòng),便可以自動(dòng)完成所有步驟。

需求:實(shí)現(xiàn)一個(gè)游戲自動(dòng)刷副本的腳本

?        let MacroCommand = function() {
            return {
                commandList: [],
                add( command ) {
                    this.commandList.push(command);
                },
                execute () {
                    for(let i = 0,command; command = this.commandList[i++];){
                        command.execute();
                    }
                }
            }
        }
        let startGameCommand = {
            execute() {
                console.log('開(kāi)始游戲')
            }
        }
        let killGhostCommand = {
            execute() {
                console.log('打怪')
            }
        }
        let giftCommand = {
            execute() {
                console.log("領(lǐng)取獎(jiǎng)勵(lì)")
            }
        }
        let outGameCommand = {
            execute() {
                console.log("退出游戲")
            }
        }
        let Game = MacroCommand();
        Game.add(startGameCommand);
        Game.add(killGhostCommand);
        Game.add(giftCommand);
        Game.add(outGameCommand);
        Game.execute();  

我們只需要為宏命令對(duì)列中添加命令,它會(huì)自動(dòng)執(zhí)行里邊的所有命令。我們只負(fù)責(zé)啟動(dòng),其他的就不需要我們管了,我們可以放心的去做其他事情,等待它自己完成。

五. 總結(jié)

命令模式中也提到了傻瓜命令智能命令,它兩的區(qū)別在于傻瓜命令中含有命令的接收者,而智能命令沒(méi)有,它直接提供請(qǐng)求。智能命令與策略模式十分相近,只是在使用上不同,策略模式中對(duì)象的目標(biāo)相同,只是實(shí)現(xiàn)目標(biāo)的算法不同,而命令模式的目標(biāo)更具有散發(fā)性。命令模式還可以完成撤銷(xiāo)、排隊(duì)的功能。

本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • javascript計(jì)時(shí)器事件使用詳解

    javascript計(jì)時(shí)器事件使用詳解

    通過(guò)使用JavaScript,能在一個(gè)設(shè)定的時(shí)間間隔之后來(lái)執(zhí)行代碼,而不是在函數(shù)被調(diào)用后立即執(zhí)行。我們稱(chēng)之為計(jì)時(shí)事件,下面對(duì)javascript計(jì)時(shí)器事件做了詳細(xì)解釋
    2014-01-01
  • 淺析javascript中function 的 length 屬性

    淺析javascript中function 的 length 屬性

    length 屬性可返回字符串中的字符數(shù)目。而function中l(wèi)ength獲取為一個(gè)函數(shù)定義的參數(shù)數(shù)目。
    2014-05-05
  • 深入了解javascript中的prototype與繼承

    深入了解javascript中的prototype與繼承

    本篇文章,小編將和大家一起深入了解javascript中的prototype與繼承,有需要的朋友可以參考一下
    2013-04-04
  • JavaScript中setUTCMilliseconds()方法的使用詳解

    JavaScript中setUTCMilliseconds()方法的使用詳解

    這篇文章主要介紹了JavaScript中setUTCMilliseconds()方法的使用詳解,是JS入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-06-06
  • 淺談ECMAScript6新特性之let、const

    淺談ECMAScript6新特性之let、const

    下面小編就為大家?guī)?lái)一篇淺談ECMAScript6新特性之let、const。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • Javascript中arguments和arguments.callee的區(qū)別淺析

    Javascript中arguments和arguments.callee的區(qū)別淺析

    這篇文章主要介紹了Javascript中arguments和arguments.callee的區(qū)別淺析,本文用一個(gè)實(shí)例來(lái)理解它們的區(qū)別,需要的朋友可以參考下
    2015-04-04
  • Javascript中Event屬性搜集整理

    Javascript中Event屬性搜集整理

    Event屬性想必大家并不陌生吧,本文整理了一些常用的,感興趣的朋友可以參考下,希望對(duì)大家有所幫助
    2013-09-09
  • 實(shí)例講解JS中數(shù)組Array的操作方法

    實(shí)例講解JS中數(shù)組Array的操作方法

    這篇文章主要介紹了JS中數(shù)組Array的操作方法,并用代碼實(shí)例講解,需要的朋友可以參考下
    2014-05-05
  • javascript少兒編程關(guān)于返回值的函數(shù)內(nèi)容

    javascript少兒編程關(guān)于返回值的函數(shù)內(nèi)容

    在本篇文章中我們給大家整理了兒童學(xué)習(xí)JS中關(guān)于返回值的函數(shù)的相關(guān)內(nèi)容知識(shí)點(diǎn),對(duì)此有興趣的參考下。
    2018-05-05
  • JavaScript從原型到原型鏈深入理解

    JavaScript從原型到原型鏈深入理解

    這篇文章主要介紹了從原型與原型鏈開(kāi)始講起,如果你想知道構(gòu)造函數(shù)的實(shí)例的原型,原型的原型,原型的原型的原型是什么,就來(lái)看看這篇文章吧。下面小編就來(lái)帶大家一起學(xué)習(xí)一下
    2019-06-06

最新評(píng)論

滕州市| 建昌县| 上饶县| 萍乡市| 内丘县| 嵩明县| 景泰县| 田阳县| 西丰县| 浦县| 赣州市| 民勤县| 泽库县| 玉溪市| 正蓝旗| 古交市| 宁海县| 临澧县| 永川市| 潞城市| 新晃| 闸北区| 平谷区| 哈尔滨市| 婺源县| 北流市| 金山区| 斗六市| 克拉玛依市| 广安市| 伊吾县| 治多县| 余干县| 霍林郭勒市| 屯昌县| 德庆县| 登封市| 海兴县| 马关县| 全南县| 巴青县|