内容提要:1. 并不是所有的浏览器都有console对象,比如IE6-IE7本身是没有开发控制台的,除非自己安装IE Dev toolbar,IE8自带DevToolbar,但如果不开启,console是undefined,会导致浏览器报错。
2. console.log本身是打出程序执行日志,这些信息本身是用于调试,发布到线上之后是否需要清除掉?
现在前端开发使用console.log是最常见的调试方式之一,在控制台能很方便的看到程序执行日志,但存在几个问题:
我们先看第一个问题
1.使用前先判断
使用console.log的时候需要先判断console是否是对象,并且console.log是否是方法
if(!!console && typeof console.log === "function"){ console.log("here is log message"); }
2.抽象成函数
但每次都这么用,势必很复杂,所以可以抽象成自己的函数,比如:
function myLog(message){ if(!!console && typeof console.log === "function"){ console.log(message || ""); } } myLog("here is log message");
这样做的缺点有几个,一个是用自己的函数去替换console.log
这种深入人心的代码,在落地执行上多少都有些困难,尤其是团队越大,越有人不遵循规范。另外,在控制台打出日志的代码行数提示时,总提示myLog那一行,而不是真正的代码逻辑行。
3.还有种方案,在JS初始化的时候对console做一次判断,防止出错。
比如:
(function(con) { 'use strict'; var prop, method; var empty = {}; var dummy = function() {}; var properties = 'memory'.split(','); var methods = ('assert,clear,count,debug,dir,dirxml,error,exception,group,' + 'groupCollapsed,groupEnd,info,log,markTimeline,profile,profiles,profileEnd,' + 'show,table,time,timeEnd,timeline,timelineEnd,timeStamp,trace,warn').split(','); while (prop = properties.pop()) con[prop] = con[prop] || empty; while (method = methods.pop()) con[method] = con[method] || dummy; })(this.console = this.console || {});
对于第二个问题
发布时如何去掉console.log的调试信息,保证线上环境的干净,也两种方案。
1.使用grunt插件grunt-removing-log
插件地址:https://github.com/ehynds/grunt-remove-logging
该插件可以自动去除console.log这样的代码,可以在实际项目中,debug模式不启用,而build模式启用。
2.使用grunt插件grunt-contrib-uglify
的Conditional compilation
grunt-contrib-uglify插件可以配置类似条件编译的特性:
grunt.initConfig({ uglify: { options: { compress: { global_defs: { "DEBUG": false }, dead_code: true } }, my_target: { files: { 'dest/output.min.js': ['src/input.js'] } } } });
详情参考 https://github.com/gruntjs/grunt-contrib-uglify
3.使用URL参数控制是否输出日志
这个需要配合第一个点,自行去定义console.log的含义。需要判断URL是否有debug=true这样的参数,如果有,则执行console.log,否则可以让console.log指向到空函数。
案例: 国内某视频网站就是全站URL加入debug=true,都可以看到调试日志,好处是方便开发快速定位问题,但缺点是如果用户知道,那么可能会泄露不该有的信息,不过…JS本身明文的,而且还可以抓包,这些问题不大。