12

我目前正忙于编写一个 javascript 库。在那个库中,我想提供一些关于控制台内容的日志记录。

function log () {
        if ((window && typeof (window.console) === "undefined") || !enableLogging) {
            return false;
        }

        function currentTime() {
            var time = new Date();
            return time.getHours() + ':' + time.getMinutes() + ':' + time.getSeconds() + '.' + time.getMilliseconds();
        }

        var args = [];

        args.push(currentTime());

        for (var i = 1; i < arguments.length; i++) { 
            args.push(arguments[i]);
        }

        switch (arguments[0]) {
            case severity.exception:
                if (window.console.exception) {
                    window.console.exception.apply(console, args);
                } else {
                    window.console.error.apply(console, args);
                }
                break;
            case severity.error:
                window.console.error.apply(console, args);
                break;
            case severity.warning:
                window.console.warning.apply(console, args);
                break;
            case severity.information:
                window.console.log.apply(console, args);
                break;
            default:
                window.console.log.apply(console, args);
        }
        return true;
    }

上面的代码展示了我的日志功能。当被调用时,我至少提供了一个严重性、一条消息和一些可选的对象(可以是 DOM 对象,如 IDBTransaction、IDBDatabase 等)。

log(severity.information, 'DB opened', db);

现在我遇到的问题是这会导致内存泄漏。问题是我传递的对象通过 console.log 方法留在内存中。有没有办法避免这种情况或清理它?

4

1 回答 1

23

传递给的对象没有被 GC 处理是可以理解的,console.log因为您需要能够在代码运行后在开发人员工具中检查它们。我根本不会将此称为问题,因为这就是调试应用程序时需要的方式,但生产代码不应执行任何控制台日志记录。

如果您仍然需要在生产中记录东西(或将其发送到某处),我建议您对对象进行字符串化:

console.log(JSON.stringify(db, null, '\t'));  // '\t' to pretty print

这里的额外好处是您在记录时确实捕获了对象的状态(而记录对象引用不能 保证 1)。

由于您正在尝试记录大型对象,请注意这样做可能会降低性能,因此如果您想在生产环境中执行此操作,请三思而后行。

1 - 似乎在最新的 Chrome中修复

于 2012-10-21T20:38:30.553 回答