JavaScript OOP:日志记录的实现

时间:2013-07-14 16:58:03

标签: javascript oop

我编写了以下代码,通过使用OOP在单独的js文件logger.js中实现日志记录。

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;
}

我想知道

  • 如果我以适当的方式实现了Logger类,则通过维护JavaScript的OOP。
  • 它会处理浏览器没有任何控制台的情况吗?
  • 如何使init()方法无法从其他js文件或方法中获取?我的意思是我怎样才能成功private

任何指针对我都非常有用。

更新

从另一个SO thread我找到了有关私有方法的信息,我改变了我的方法:

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未定义的错误。

1 个答案:

答案 0 :(得分:3)

回答你的问题:

  • 你的课程实现有点奇怪。您正在使用闭包访问console变量,将其作为Logger中的属性更有意义。
  • 如果浏览器没有控制台,则不会出现错误(但记录器不会执行任何操作)
  • 要使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");

代码在这里以JSFiddle的形式提供:http://jsfiddle.net/mtufW/

相关问题