JavaScript-OOP:日志记录的实现
我已经编写了以下代码,通过使用OOP在单独的js文件logger.js中实现日志记录JavaScript-OOP:日志记录的实现,javascript,oop,Javascript,Oop,我已经编写了以下代码,通过使用OOP在单独的js文件logger.js中实现日志记录 var console; function Logger() { init(); } var init = function() { if(!window.console){ console = { log: function(message){}, info: function(message){},
var console;
function Logger() {
init();
}
var init = function() {
if(!window.console){
console = {
log: function(message){},
info: function(message){},
warn: function(message){},
error: function(message){}
};
} else {
console = window.console;
}
};
Logger.prototype.log = function(message) {
console.log(message);
}
Logger.prototype.logInfo = function(message) {
console.info(message);
}
Logger.prototype.logWarn = function(message) {
console.warn(message);
}
Logger.prototype.logError = function(message) {
console.error(message);
}
我从另一个js文件site.js中使用它:
var logger = new Logger(); //global variable
var getComponentById = function(id) {
var component = null;
if(id) {
try {
component = AdfPage.PAGE.findComponentByAbsoluteId(id);
}catch(e){
logger.logError(e);
}
}
return component;
}
我在想
- 如果我通过维护JavaScript的OOP以正确的方式实现了
类Logger
- 它能处理浏览器没有任何控制台的情况吗
- 如何使
方法无法从其他js文件或方法访问?我的意思是,我怎样才能使它成为私有的init()
function Logger() {
init();
}
Logger.prototype = (function() {
var console;
var init = function() {
if(!window.console){
this.console = {
log: function(message){},
info: function(message){},
warn: function(message){},
error: function(message){}
};
} else {
this.console = window.console;
}
};
return {
constructor: Logger,
log: function(message) {
this.console.log(message);
},
logInfo: function(message) {
this.console.info(message);
},
logWarn: function(message) {
this.console.warn(message);
},
logError: function(message) {
this.console.error(message);
}
};
})();
但在这种情况下,我得到的错误是未定义
init
。要回答您的问题:
- 您对该类的实现有点奇怪。使用闭包访问
变量,将其作为记录器上的属性更有意义控制台
- 如果浏览器没有控制台,则不会出现错误(但记录器不会执行任何操作)
- 要使init函数私有,可以将其包装在IIFE(立即调用的函数表达式)中
// Create the Logger function with an IIFE, this keeps all of the private
// variables out of the global scope, the only thing in the global scope
// is the function returned by the IIFE.
var Logger = (function (w) {
var Logger,
DummyConsole;
DummyConsole = function () {
this.log = function (message) {
alert(message);
};
this.info = function (message) {
// Implement however you want.
};
this.warn = function (message) {
// ...
};
this.error= function (message) {
// ...
};
};
Logger = function () {
if (!w.console) {
this.console = new DummyConsole();
} else {
this.console = w.console;
}
};
Logger.prototype.log = function(message) {
this.console.log(message);
};
Logger.prototype.logInfo = function(message) {
this.console.info(message);
};
Logger.prototype.logWarn = function(message) {
this.console.warn(message);
};
Logger.prototype.logError = function(message) {
this.console.error(message);
};
return Logger;
}(window));
// create a logger instance to check that the Logger class logs to the console.
var a = new Logger();
a.log("hello");
// Remove the console.
window.console = null;
// Create a new logger checking that it falls back to the dummy console implementation.
var b = new Logger();
// An (annoying) alert is shown.
b.log("Hi");
代码可以作为JSFIDLE在这里使用:“在一个单独的JS文件中…”听起来好像你说你实际上是要通过JSIDLE将日志条目提交到一个JS文件中。将“console”的所有实例重命名为诸如“console2”之类的其他东西来测试浏览器行为,如果没有定义的话。谢谢Rob,我有一个疑问。您使用了this.console,但未在任何地方声明此控制台字段。我已经看到了工作示例。我想知道这个控制台是如何工作的?窗口对象被传递给函数。检查这段代码Logger=function(){if(!w.console){this.console=new dummconsole();}否则{this.console=w.console;};是的,我以前见过这个代码。我担心的是,如果您使用
this.console
,那么就会有var控制台代码>在类范围中定义。但事实并非如此,尽管代码运行良好。我的问题是怎么做?我们不需要在某个地方声明var console
?您正在这个对象上定义console
。在构造函数的上下文中是新创建的对象。类似于var a={};a、 someProp=“你好”代码>。在对象上定义someProp时,您不需要var someProp
。@TapasBose-是的,您是对的:您可以只定义一次,第二次只是为了证明如果控制台不可用,它将使用内部实现。