6

我编写了以下代码,通过使用 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 线程中,我找到了有关私有方法的信息,并更改了方法:

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

4

1 回答 1

3

要回答您的问题:

  • 你的类的实现有点奇怪。您正在使用console闭包访问变量,将其作为 Logger 上的属性更有意义。
  • 如果浏览器没有控制台,你不会得到错误(但记录器不会做任何事情)
  • 为了使您的初始化函数私有,您可以将其包装在 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/

于 2013-07-14T17:38:07.123 回答