4
\$\begingroup\$

I wrote this just for some fun and also to practise my ES6 skills. When user key in the Konami Cheat Code(⬆️⬆️⬇️⬇️⬅️➡️⬅️➡️🅱️🅰️↩️) anywhere in the page, it should trigger a callback. In the following example, it should trigger an alert.

What could be improved?

Are there more ES6 features I could use in this code?

const {onKonamiSequenceTriggered, clearKonamiSequanceTriggered} = (() => {
    const konamiSequence = ["ARROWUP", "ARROWUP", "ARROWDOWN", "ARROWDOWN", "ARROWLEFT", "ARROWRIGHT", "ARROWLEFT", "ARROWRIGHT", "B", "A", "ENTER"];
    konamiSequence.reverse();
    let currentSequence = Array.prototype.slice.call(konamiSequence);

    const callbacks = {};

    let eventId = 0;

    const onKonamiSequenceTriggered = callback => {
        callbacks[eventId] = callback;
        return eventId++;
    };

    const clearKonamiSequanceTriggered = id => delete callbacks[id];

    document.addEventListener("keyup", event => {
        if (event.key.toUpperCase() !== currentSequence.pop()) {
            currentSequence = Array.prototype.slice.call(konamiSequence);
        }
        if (!currentSequence.length) {
            Object.values(callbacks).forEach(callback => {
                try {
                    callback();
                } catch (e) {
                    console.error(e);
                }
            });
            currentSequence = Array.prototype.slice.call(konamiSequence);
        }
    });

    return {
        onKonamiSequenceTriggered,
        clearKonamiSequanceTriggered
    };
})();

onKonamiSequenceTriggered(() => alert("You've got it!"));
\$\endgroup\$
  • \$\begingroup\$ Tested on chrome (I'm not too worried about cross-browser support, If I were to use it in production I would use babel to transpile it) \$\endgroup\$ – rabbit.aaron Jun 28 at 8:43
2
\$\begingroup\$

You clone an array 3 times by using:

currentSequence = Array.prototype.slice.call(konamiSequence);

but with ES6, you can also use the spread operator to clone an array:

currentSequence = [... konamiSequence];

It took me a while to figure out the complex outer construction in your code:

const {onKonamiSequenceTriggered, clearKonamiSequanceTriggered} = (() => {

    .... actual code ...

    return {
        onKonamiSequenceTriggered,
        clearKonamiSequanceTriggered
    };
})();

It is an object destructuring assignment which is assigned two methods by using a self-executing anonymous function. I guess the advantage is that you can use local scope within the anonymous function. Note that you could leave out all of the code, in the excerpt above, and your code would still work, albeit completely in global scope.

I did find code on Stack Overflow which looks similar, but it is obviously not the same.

I'm not an Javascript expert, so that's all I have. I learned something from this, but I still think that Javascript has some awful language constructs (in other words: I'm not used to it).

\$\endgroup\$
  • \$\begingroup\$ Good suggestion on the Spread operator! And yes, I use the local scope so the konamiSequence won't be tampered with. I've looked at other solutions in stack overflow, using index instead of copying array all the time seems like a good idea! Thank you for the effort! \$\endgroup\$ – rabbit.aaron Jun 28 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.