我只是想学习和理解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:由于我对代码进行了一些修改,因此问题与最初的问题完全不同。
答案 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
对象仅公开Print
和Log
属性。
答案 1 :(得分:2)
我目前看到的唯一问题是,你实际上是暴露两个全局变量,window.Console
这很好,因为你想在那里暴露它,$c
。
这是因为你没有在作业中使用var
语句,应该是:
var $c = this.Console;
如果您不使用它,$c
将是全球性的。
除此之外,也许您可能希望处理命名约定,通常是在JavaScript中,您几乎命名camelCase
中的所有内容,PascalCase
中只有constructor functions,这只是一个注释,我个人试图坚持这个惯例,但取决于你和你的团队。
编辑关于使用innerHTML
属性进行的连接,如果您将在div中处理大量数据,我建议您使用DOM操作,而不是替换每次都是innerHTML
。
通过DOM操作,我可以使用document.createElement
和element.appendChild
将您的日志消息创建为div的嵌套DOM元素。
答案 2 :(得分:0)
我尝试使用与Firebug和IE Developer Toolbar相同的API,以便您可以很好地降级。在这个方向上的一个构建是如果window.console已经存在,那么不要执行你的代码。这样你就可以获得本机调试器,否则你将获得实现。