Cross Browser Support for Console.log()

Almost all programmers use browsers Javascript-console for debugging.
The console is built into Chrome, Opera, IE and installed with Firebug in Firefox.
But she has a couple of disadvantages, which can be very easy to fix.

console.log('Cross Browser Support!');

They are:

Lets fix these problems quickly and easily!

The first thing we need to do – replace the original console object with our own one. The original console keeps in the variable original.

(function () {
   var global   = this;
   var original = global.console;
   var console  = global.console = {};
})();

Now we need to implement all the methods of the original console, if they are:

(function () {
   var global   = this;
   var original = global.console;
   var console  = global.console = {};
   var methods = ['assert', 'count', 'debug', 'dir', 'dirxml', 'error', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'trace', 'warn'];
   for (var i = methods.length; i--;) {
      (function (methodName) {
         console[methodName] = function () {
            if (original && methodName in original) {
               original[methodName].apply(original, arguments);
            }
         };
      })(methods[i]);
   }
})();

Now we can use the console out of the context, for example:

Run console.log onclick:

$('#my-element').click(console.log);

Short alias:

var log = console.log;
for (var i = 0; i < 10; i++) log(i);

Another good feature, turning off console on production:

if (typeof log != 'function') {
	log = function() {};
}

Methods time and timeEnd ported from Firebug:

var original = global.console;
   var console  = global.console = {};
   if (original && !original.time) {
      original.time = function(name, reset){
         if (!name) return;
         var time = new Date().getTime();
         if (!console.timeCounters) console.timeCounters = {};
         
         var key = "KEY" + name.toString();
         if(!reset && console.timeCounters[key]) return;
         console.timeCounters[key] = time;
      };

      original.timeEnd = function(name){
         var time = new Date().getTime();
            
         if(!console.timeCounters) return;
         
         var key  = "KEY" + name.toString();
         var timeCounter = console.timeCounters[key];
         
         if (timeCounter) {
            var diff = time - timeCounter;
            var label = name + ": " + diff + "ms";
            console.info(label);
            delete console.timeCounters[key];
         }
         return diff;
      };
   }

Full source:

(function (console) {

var i,
	global  = this,
	fnProto = Function.prototype,
	fnApply = fnProto.apply,
	fnBind  = fnProto.bind,
	bind    = function (context, fn) {
		return fnBind ?
			fnBind.call( fn, context ) :
			function () {
				return fnApply.call( fn, context, arguments );
			};
	},
	methods = ['assert', 'count', 'debug', 'dir', 'dirxml', 'error', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log', 'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd', 'trace', 'warn'],
	emptyFn = function(){},
	empty   = {},
	timeCounters;

for (i = methods.length; i--;) empty[methods[i]] = emptyFn;

if (console) {

	if (!console.time) {
		console.timeCounters = timeCounters = {};

		console.time = function(name, reset){
			if (name) {
				var time = +new Date, key = "KEY" + name.toString();
				if (reset || !timeCounters[key]) timeCounters[key] = time;
			}
		};

		console.timeEnd = function(name){
			var diff,
				time = +new Date,
				key = "KEY" + name.toString(),
				timeCounter = timeCounters[key];

			if (timeCounter) {
				diff  = time - timeCounter;
				console.info( name + ": " + diff + "ms" );
				delete timeCounters[key];
			}
			return diff;
		};
	}

	for (i = methods.length; i--;) {
		console[methods[i]] = methods[i] in console ?
			bind(console, console[methods[i]]) : emptyFn;
	}
	console.disable = function () { global.console = empty;   };
	  empty.enable  = function () { global.console = console; };

	empty.disable = console.enable = emptyFn;

} else {
	console = global.console = empty;
	console.disable = console.enable = emptyFn;
}

})( typeof console === 'undefined' ? null : console );

// Optional
var log = console.log, error = console.error;

Sources on Github.

Leave a Reply