JavaScript OOP:日志记录的实现

Tap*_*ose 6 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);
}
Run Code Online (Sandbox Code Playgroud)

我从另一个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;
}
Run Code Online (Sandbox Code Playgroud)

我在想

  • 如果我Logger以适当的方式实现了类,则通过维护JavaScript的OOP.
  • 它会处理浏览器没有任何控制台的情况吗?
  • 如何使init()其他js文件或方法无法访问方法?我的意思是我该怎么做呢private

任何指针都对我很有帮助.

更新

从另一个SO线程我发现有关私有方法的信息,我改变了我的方法:

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);
        }
    };
})();
Run Code Online (Sandbox Code Playgroud)

但在这种情况下,我收到的错误init是未定义的.

Rob*_*obH 3

回答您的问题:

  • 你的类的实现有点奇怪。您使用console闭包访问变量,将其作为记录器上的属性更有意义。
  • 如果浏览器没有控制台,您不会收到错误(但记录器不会执行任何操作)
  • 为了使 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");
Run Code Online (Sandbox Code Playgroud)

代码可在此处作为 JSFiddle 获取:http ://jsfiddle.net/mtufW/

  • 您正在“this”对象上定义“console”。在构造函数的上下文中,它是新创建的对象。类似于`var a = {}; a.someProp =“你好”;`。您不需要“var someProp”,因为您在对象上定义它。 (2认同)