在生产 JavaScript 代码中留下“console.log()”调用是个坏主意?

Posted

技术标签:

【中文标题】在生产 JavaScript 代码中留下“console.log()”调用是个坏主意?【英文标题】:Bad idea to leave "console.log()" calls in your production JavaScript code? 【发布时间】:2010-11-09 23:52:42 【问题描述】:

我的 javascript 中有一堆 console.log() 调用。

我应该在部署到生产环境之前将它们注释掉吗?

我想把它们留在那里,这样以后如果我需要进行更多调试,我就不必费心重新添加 cmets。这是个坏主意吗?

【问题讨论】:

对于那些正在寻找这个问题的 Angular 版本的人:***.com/questions/42307317/… 【参考方案1】:

它会导致 Javascript 错误,终止包含错误的 Javascript 块的执行。

但是,您可以定义一个在 Firebug 未激活时不执行任何操作的虚拟函数:

if(typeof console === "undefined") 
    console =  log: function()   ;

如果您使用log 以外的任何方法,您也需要将这些方法存根。

【讨论】:

谢谢。这看起来是一个不错的解决方法。让我看看我是否理解它。您是说如果控制台未定义,则将控制台设置为空函数。我不明白'log'之后的冒号语法。那是做什么的,为什么在 "console=" 之后的所有东西都在大括号内? 大括号定义了一个对象字面量:developer.mozilla.org/en/Core_JavaScript_1.5_Guide/…,而“function() ”位定义了一个匿名函数,它不接受任何参数并且什么都不做。 (它仍然可以使用参数调用“console.log(foo)”,因为 JS 不在乎你调用参数太多或太少的函数。) 明白。也感谢您的链接。 优秀的解决方案人! :-) 前几天我刚遇到这个问题。我的页面只有在 FireBug 开启时才能在 FF 中工作,并且它会随机停止 IE 中的某些操作。我就像WTF!?!然后,我意识到我的 console.log 调用仍然在那里,我必须通过并删除它们。我现在可能会将您的解决方案添加到我的主 JS 文件中,并且再也不用担心这种不幸的情况了。 我有一个小(单元测试)项目,可以帮助您使用各种不同的控制台方法以尽可能少的代码完成此任务。它位于:github.com/andyet/ConsoleDummy.js【参考方案2】:

正如其他人已经指出的那样,将其保留在某些浏览器中会导致错误,但可以通过放入一些存根来解决这些错误。

但是,我不仅会注释掉它们,还会直接删除这些行。不这样做似乎很草率。也许我很迂腐,但我认为“生产”代码根本不应该包含“调试”代码,即使是注释形式。如果您完全保留 cmets,这些 cmets 应该描述代码在做什么,或者它背后的原因——而不是禁用的代码块。 (虽然,大多数 cmets 应该在您的缩小过程中自动删除。您正在最小化,对吗?)

另外,在使用 JavaScript 的几年中,我不记得曾经回到一个函数并说“哎呀,我希望我把这些 console.logs 留在原处!”一般来说,当我“完成”了一个函数的工作,然后又不得不回到它时,我会回来解决一些其他问题。无论新问题是什么,如果上一轮工作的 console.logs 可能有所帮助,那么我会在第一时间发现问题。换句话说,如果我回过头来,我不太可能需要与以前完全相同的调试信息。

只有我的两分钱......祝你好运!

【讨论】:

问题通常出现在生产周期中,因为正在调试或测试某些东西,人们在没有开发控制台的开发团队之外查看它。我个人的偏好是不要让应用程序死在它们上面,这样我们就不会接到诸如“你的新代码对我没有任何作用”之类的电话。 永久调试线非常棒。它们意味着您通常不必四处寻找错误的来源,而是可以立即看到正在发生的事情。有许多代码部分的日志语句不会产生任何显着的性能差异。 良好的日志记录应该可用于多种用途。说 log() 语句只对调试一个问题有用,这让我想起了不知道如何编写正确日志记录的人的 Java 日志记录。 简而言之:记录主要(高级)决策和事件处理,因此可以遵循业务、高级 UI 和主要事件处理流程。这些对于工程应用程序具有永久价值。记录“进入方法 A”、“离开方法 A”、“param1 77”是 OTOH 不好的记录。【参考方案3】:

如果您有部署脚本,则可以使用它来去除对 console.log 的调用(并缩小文件)。

当您使用它时,您可以通过 JSLint 抛出您的 JS 并记录违规行为以供检查(或阻止部署)。

这是一个很好的例子,说明了您为什么要自动化部署。如果您的流程允许您发布一个包含 console.logs 的 js 文件,那么在某些时候您这样做。

【讨论】:

【参考方案4】:

据我所知,没有比以下 45 个字符更短的方法来删除 console.log

window.console||(console=log:function());

这是 3 个不同版本中的第一个,具体取决于您要删除的控制台方法,所有这些方法都很小,并且都已在 IE6+ 和现代浏览器中进行了测试。

其他两个版本涵盖了不同的其他控制台方法。一个涵盖四个基础知识,另一个涵盖所有已知的 firebug 和 webkit 控制台方法。再次,以尽可能小的文件大小。

该项目在 github 上:https://github.com/andyet/ConsoleDummy.js

如果您能想到任何进一步减少代码的方法,欢迎贡献。

-- 编辑 -- 2012 年 5 月 16 日

我已经改进了这段代码。它仍然很小,但增加了打开和关闭控制台输出的功能:https://github.com/HenrikJoreteg/andlog

原来是featured on The Changelog Show

【讨论】:

【参考方案5】:

如果对象不存在,您至少应该创建一个虚拟console.log,这样您的代码就不会在未安装 firebug 的用户机器上抛出错误。

另一种可能性是仅在“调试模式”下触发日志记录,即如果设置了某个标志:

if(_debug) console.log('foo');
_debug && console.log('foo');

【讨论】:

同意 Cristoph 的观点,对于 Safari 来说这不是问题,但在其他浏览器中它会抛出错误并且可能会阻止 javascript 继续运行。一般来说不是一个好主意...【参考方案6】:

希望它对某人有所帮助——我不久前为它写了一个包装器,它比公认的解决方案更灵活。

显然,如果您使用其他方法,例如 console.info 等,您可以复制效果。完成暂存环境后,只需将默认 C.debug 更改为 false 即可进行生产,您无需更改任何其他代码/删除行等。稍后返回并进行调试非常容易。

var C = 
    // console wrapper
    debug: true, // global debug on|off
    quietDismiss: false, // may want to just drop, or alert instead
    log: function() 
        if (!C.debug) return false;

        if (typeof console == 'object' && typeof console.log != "undefined") 
            console.log.apply(this, arguments); 
        
        else 
            if (!C.quietDismiss) 
                var result = "";
                for (var i = 0, l = arguments.length; i < l; i++)
                    result += arguments[i] + " ("+typeof arguments[i]+") ";

                alert(result);
            
        
    
; // end console wrapper.

// example data and object
var foo = "foo", bar = document.getElementById("divImage");
C.log(foo, bar);

// to surpress alerts on IE w/o a console:
C.quietDismiss = true;
C.log("this won't show if no console");

// to disable console completely everywhere:
C.debug = false;
C.log("this won't show ever");

【讨论】:

【参考方案7】:

这似乎对我有用...

if (!window.console) 
    window.console = 
        log: function () ,
        group: function () ,
        error: function () ,
        warn: function () ,
        groupEnd: function () 
    ;

【讨论】:

【参考方案8】:

我想我会分享不同的观点。在 PCI 应用程序中让这种类型的输出对外界可见会导致您不合规。

【讨论】:

我从来没有想过。谢谢。 他可能指的是en.wikipedia.org/wiki/… ... 那么,当有人在你的网站上右击查看源代码时,你是否不合规?【参考方案9】:

我同意控制台存根是一个好方法。我尝试了各种控制台插件,代码 sn-ps,包括一些相当复杂的。他们都在至少一个浏览器中遇到了一些问题,所以我最终选择了一些简单的东西,如下所示,这是我见过的其他 sn-ps 和 YUI 团队的一些建议的合并。它似乎可以在 IE8+、Firefox、Chrome 和 Safari(适用于 Windows)中运行。

// To disable logging when posting a production release, just change this to false.
var debugMode = false;

// Support logging to console in all browsers even if the console is disabled. 
var log = function (msg) 
    debugMode && window.console && console.log ? console.log(msg) : null;
;

注意:它支持通过标志禁用登录到控制台。也许您也可以通过构建脚本自动执行此操作。或者,您可以公开 UI 或其他一些机制以在运行时翻转此标志。当然,您可以变得更复杂,包括日志级别、基于日志阈值的 ajax 提交日志(例如,所有错误级别语句都传输到服务器以存储在那里等)。

许多关于日志记录的线程/问题似乎将日志语句视为调试代码,而不是代码仪器。因此希望删除日志语句。当应用程序在野外并且不再那么容易附加调试器或从用户或通过支持向您提供信息时,插桩非常有用。你永远不应该记录任何敏感的东西,不管它被记录在哪里,所以隐私/安全不应该受到损害。一旦您将日志记录视为工具,它现在就变成了生产代码,并且应该按照相同的标准编写。

对于使用越来越复杂的 javascript 的应用程序,我认为检测至关重要。

【讨论】:

【参考方案10】:

正如其他人所提到的,它会在大多数浏览器中引发错误。在 Firefox 4 中它不会抛出错误,消息会记录在 Web 开发者控制台中(Firefox 4 中的新功能)。

我真正喜欢的此类错误的一种解决方法是de&&bug:

var de = true;
var bug = function()  console.log.apply(this, arguments); 

// within code
de&&bug(someObject);

【讨论】:

【参考方案11】:

一个不错的单行:

(!console) ? console.log=function() : console.log('Logging is supported.');

【讨论】:

以上是关于在生产 JavaScript 代码中留下“console.log()”调用是个坏主意?的主要内容,如果未能解决你的问题,请参考以下文章

查询生产耗时

错误:您没有收到 MultipartFile

JavaScript之变量提升

vue生产环境清除console.log

javascript解析器原理

如何在javascript中完全获取带有重复键的JSON