在尝试改进此工具的同时学习JavaSCript,请评论这个简单的JavaScript日志记录工具

时间:2009-12-15 04:21:26

标签: javascript cross-browser anonymous-function

我只是想学习和理解jQuery源代码(到目前为止,X_X没什么成功),以提高我的JavaScript技能。随着我对JavaScript的理解增加,我想出了这个小小的日志/调试工具。至于我的JavaScript水平,我在这里发布代码供人们判断和审核。所以我可以从评论中学习。有人可以指出潜在的问题,改进吗?我试图封装控制台实现并将其映射到窗口。$ 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:由于我对代码进行了一些修改,因此问题与最初的问题完全不同。

3 个答案:

答案 0 :(得分: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属性。

答案 1 :(得分:2)

我目前看到的唯一问题是,你实际上是暴露两个全局变量,window.Console这很好,因为你想在那里暴露它,$c

这是因为你没有在作业中使用var语句,应该是:

 var $c = this.Console;

如果您不使用它,$c将是全球性的。

除此之外,也许您可​​能希望处理命名约定,通常是在JavaScript中,您几乎命名camelCase中的所有内容,PascalCase中只有constructor functions,这只是一个注释,我个人试图坚持这个惯例,但取决于你和你的团队。

编辑关于使用innerHTML属性进行的连接,如果您将在div中处理大量数据,我建议您使用DOM操作,而不是替换每次都是innerHTML

通过DOM操作,我可以使用document.createElementelement.appendChild将您的日志消息创建为div的嵌套DOM元素。

答案 2 :(得分:0)

我尝试使用与Firebug和IE Developer Toolbar相同的API,以便您可以很好地降级。在这个方向上的一个构建是如果window.console已经存在,那么不要执行你的代码。这样你就可以获得本机调试器,否则你将获得实现。