1

JavaScript のスキルを向上させるために、jQuery のソース コードを学習して理解しようとしていました (これまでのところ、ほとんど成功していません X_X)。JavaScript の理解が深まるにつれ、この小さなロギング/デバッグ ツールを思いつきました。JavaScript の私のレベルでは、人々が判断して監査できるように、ここにコードを投稿しています。したがって、コメントから学ぶことができる可能性があります。誰かが潜在的な問題、改善点を指摘できますか? コンソールの実装をカプセル化し、window.$console (グローバル スコープを台無しにする唯一の場所) にマップしようとしました。

(function() {
    var proxy = {}, //use private proxy object to prevent binding to global (window) object
        _id = "",
        _warning = false;
        results = {};

    if (this.$console) { //check if $console exists in global (window)
        warning("$console is conflicting with existing object and could not be mapped.");
    }
    else {
        this.$console = proxy; //if undefined we then map proxy to global (window) object
    }

    proxy.init = function(id) { //map the display ol html element on the page
        _id = id;
        results = document.getElementById(id);
        return this;
    }

    proxy.log = function(msg) {
        append(msg);
        return this;
    };

    proxy.assert = function(pass, msg) {
        var html = (pass) ? "<b style=\"color: green;\">Pass</b>, " + msg
                    : "<b style=\"color: red;\">Fail</b>, " + msg ;
        append(html);
        return this;
    }

    proxy.error = function(msg) {
        var html = "<b style=\"color: red;\">Error</b>, " + msg + "";
        append(html);
        return this;
    }

    function append(msg) {
        if (results != null) {
            results.appendChild(getChild("li", msg));
        }
        else {
            warning("Message could not be appended to element with \"Id: " + _id + "\".");
        }
        return this;
    };

    function getChild(type, html) {
        var child = document.createElement(type);
        child.innerHTML = html;
        return child;
    }

    function warning(msg) {
        if (!_warning) {
            _warning = true;
            alert(msg);
        }
    }

    return proxy;
}());

使用法

$console.init("console").log("hello world");
$console.assert(true, "This is a pass.");

ps: コードにいくつかの修正を加えたため、質問は元のものとはかなり異なります。

4

3 に答える 3

4

問題なく動作するようです。ただし、無名関数の使用は少しわかりにくいと思います。にはプライベート データがないためConsole、次のように定義してみませんか。

var Console = {

    instance: document.getElementById('console'),

    Print: function (msg) {
        this.instance.innerHTML += msg;
        return this;
    },

    Log: function (msg) {
        this.Print("<br/>").Print(msg);
    }
};

また、 の代入で使用されている無名関数も削除しましたinstance。これは、何もしていないように見えるためです。

編集

無名関数の評価手法は、通常、宣言された変数を非表示にするために使用されます。議論についてはhttp://yuiblog.com/blog/2007/06/12/module-pattern/を参照してください。

たとえば、instanceプロパティを非表示にする場合は、次の方法で無名関数を使用してそれを実現できます。

var Console = (function () {

    // object containing public members to be returned
    var c = {};

    // not visible outside anonymous function
    var instance = document.getElementById('console');

    // a 'public' property
    c.Print = function (msg) {
        instance.innerHTML += msg;
        return this;
    };

    // a 'public' property
    c.Log = function (msg) {
        this.Print("<br/>").Print(msg);
    };

    return c;
}());

結果のオブジェクトは、 プロパティとプロパティConsoleのみを公開します。PrintLog

于 2009-12-15T04:31:50.077 に答える
2

私がこれまでに見た唯一の問題は、実際に 2 つのグローバルwindow.Consoleを公開していることです$c

これはvar、割り当てでステートメントを使用していないためです。次のようにする必要があります。

 var $c = this.Console;

使用しない場合は、$cグローバルになります。

それとは別に、命名規則に取り組みたいと思うかもしれません。通常、JavaScript では のほとんどすべてに名前を付け、ではコンストラクター関数camelCaseのみに名前を付けます。これは単なるコメントです。私は個人的にその規則を固守しようとしますが、あなたとあなたのチーム次第です。PascalCase

編集:プロパティを使用して行われた連結について、innerHTMLdiv で大量のデータを処理する場合は、innerHTML毎回全体を置き換えるのではなく、DOM 操作を使用することをお勧めします。

DOM 操作によって、および を使用して、div のネストされた DOM 要素としてログ メッセージを作成することを参照しますdocument.createElementelement.appendChild

于 2009-12-15T04:30:41.280 に答える
0

Firebug と IE Developer Toolbar が公開しているものと同じ API を使用して、適切にデグレードできるようにします。その方向へのビルドの 1 つは、window.console が既に存在する場合は、コードを実行しないことです。そうすれば、利用可能な場合はネイティブ デバッガーを取得できます。それ以外の場合は、実装を取得できます。

于 2009-12-15T04:42:31.667 に答える