htsign's blog

ノンジャンルで書くつもりだけど技術系が多いんじゃないかと思います

今更Brainf*ckインタプリタ

何番煎じだよって感じのネタ。
まぁ、JavaScriptの練習ですね。

https://dl.dropboxusercontent.com/u/414379/www/brainf_ck/brainf_ckInterpreter.html

素地自体はあっさり作れたんですが、細かいところをアレも気になるコレも気になるってな感じでちょこちょこ弄っていたら、なんだかんだで3日くらい開発にかかってしまいました。

デザインには全く気を払っていないのでCSSは未使用です。


ところでイベントリスナの登録用メソッドについては、エラーハンドリングとか全然してませんしIE8以下全滅ですけど、それなりに流用できるのではないかな?と思います。
こんなの↓

HTMLElement.prototype.addEvent = function(){
    var args = Array.apply(null, arguments);
    
    switch (args.length) {
        case 1: addEventObj.call(this, args[0]); break;
        case 2:
            if (typeof args[0] === "string") {
                this.addEventListener(args[0], args[1].bind(this), false);
            }
            else {
                addEventArr.call(this, args[0], args[1]);
            }
            break;
    }
    
    function addEventObj(eventSet){
        var DELIMITER = ",";
        
        var name = "";
        var event = {};
        var namesArray = [];
        
        for (name in eventSet) {
            event = eventSet[name];
            
            if (name.indexOf(DELIMITER) !== -1) {
                namesArray = name.split(DELIMITER).map(function(e){ return e.trim() });
                addEventArr.call(this, namesArray, event);
            }
            else {
                this.addEventListener(name, event.bind(this), false);
            }
        }
    }
    function addEventArr(eventNameList, event) {
        eventNameList.forEach(function(e){
            this.addEventListener(e, event.bind(this), false);
        }, this);
    }
};

※ここではインデント浅くするためにprototypeに直接生やしてますが、元コードではObject.defineProperty使ってます。

これによって、例えば

var sample = document.getElementById("sample");

// 普通の単なるエイリアスっぽい書き方
sample.addEvent("click", function(){
    alert("hello!");
});

// 一気に複数リスナ指定
sample.addEvent(["click", "focus"], function(){
    alert("hello!");
});

// 一気に複数イベント指定
sample.addEvent({
    "click": function(){
        alert("hello!");
    },
    "focus": function(){
        alert("yeah!");
    }
});

// もちっと複雑に
sample.addEvent({
    "click": function(){
        alert("hello!");
    },
    "focus, blur": function(){
        alert("yeah!");
    }
});

みたいなコードでイベントリスナの追加ができるようになります。
あれ、それjQueryでできるんじゃね?と思ったアナタはスルドイ!!

でも最後の複雑な複数イベント登録はプラグイン無しの素のjQueryではできないと思っているんですが、どうでしょうか。実はできるのかな…。うーん。
まぁjQueryを使わないところに価値があるということで。


この記事書き始めてから思ったけど、callとかbindとか使わなくても、先頭の方でvar _this = this;とか書いておいてそれ参照すりゃ済む話ですね…。

追記 (2014/05/24 23:42)

今までIE11でしかテストしてなかったから全然気づかなかったけど、Firefox, Chromeで動かすとイベントハンドリングがうまく動いていない。
これは酷い。
でもFirefoxはともかくとしてChromeは普段使ってないからどうでもいいや。
気が向いたら修正しますが多分やりますん。