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:
- Errors when the console is not defined
- Inability to use outside the context of
- Inability to turn off during the production
- Non Cross Browser
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.