Does the Chrome developer console have any aliases? [duplicate] - javascript

Is it possible to somehow access to console.log after it gets overwritten?
window.console = { log: function (msg) { alert(msg); }, /* etc... */ };
Would be it be possible to regain the original console.log functionality?

You can back up the console before overwriting it.
var oldConsole = window.console;
window.console = { log:function(msg){alert(msg)} //...};
Then you can use the oldConsole variable.
oldConsole.log('test');
If you can't back it up, you can create an iFrame, and then steal the console from there (this may not work in all browsers):
var i = document.createElement('iframe');
i.style.display = 'none';
document.body.appendChild(i);
window.console = i.contentWindow.console;
Demo: http://jsfiddle.net/jcG7E/2

Edit (2017-04-08): This advise is outdated, in Firefox 52 and Chrome 57 console is no longer defined on the window prototype and deleting it will really delete it.
At least with the console object defined by Firefox and Chrome, you can simply delete the overwritten property to restore the original one:
window.console = {};
delete window.console;
window.console.log("This works!");
This works as if the console property were defined on the prototype of the window object - except that it isn't, the browsers are doing some magic here.

It's not possible. Except if whoever has overwritten it has included some code to undo it.

var customLog = {
oriLog: '',
Log: function(){
// create string to display
var displaystring = '';
for (var i = 0, len = arguments.length; i < len; i++) {
displaystring += arguments[i];
if (i + 1 != len)
displaystring += ', ';
}
alert(displaystring);
customLog.oriLog(arguments);
}
}
window.onload = function(){
if (console != null) {
customLog.oriLog = console.log;
console.log = customLog.Log;
}
}

Related

how to mirror console.log in html page text box [duplicate]

Is it possible to extend the console object?
I tried something like:
Console.prototype.log = function(msg){
Console.prototype.log.call(msg);
alert(msg);
}
But this didn't work.
I want to add additional logging to the console object via a framework like log4javascript and still use the standard console object (in cases where log4javascript is not available) in my code.
Thanks in advance!
Try following:
(function() {
var exLog = console.log;
console.log = function(msg) {
exLog.apply(this, arguments);
alert(msg);
}
})()
You Can Also add log Time in This Way :
added Momentjs or use New Date() instead of moment.
var oldConsole = console.log;
console.log = function(){
var timestamp = "[" + moment().format("YYYY-MM-DD HH:mm:ss:SSS") + "] ";
Array.prototype.unshift.call(arguments, timestamp);
oldConsole.apply(this, arguments);
};
It's really the same solution some others have given, but I believe this is the most elegant and least hacky way to accomplish this. The spread syntax (...args) makes sure not a single argument is lost.
var _console={...console}
console.log = function(...args) {
var msg = {...args}[0];
//YOUR_CODE
_console.log(...args);
}
For ECMAScript 2015 and later
You can use the newer Proxy feature from the ECMAScript 2015 standard to "hijack" the global console.log.
Source-Code
'use strict';
class Mocker {
static mockConsoleLog() {
Mocker.oldGlobalConsole = window.console;
window.console = new Proxy(window.console, {
get(target, property) {
if (property === 'log') {
return function(...parameters) {
Mocker.consoleLogReturnValue = parameters.join(' ');
}
}
return target[property];
}
});
}
static unmockConsoleLog() {
window.console = Mocker.oldGlobalConsole;
}
}
Mocker.mockConsoleLog();
console.log('hello'); // nothing happens here
Mocker.unmockConsoleLog();
if (Mocker.consoleLogReturnValue === 'hello') {
console.log('Hello world!'); // Hello world!
alert(Mocker.consoleLogReturnValue);
// anything you want to do with the console log return value here...
}
Online Demo
Repl.it.
Node.js users...
... I do not forget you. You can take this source-code and replace window.console by gloabl.console to properly reference the console object (and of course, get rid of the alert call). In fact, I wrote this code initially and tested it on Node.js.
// console aliases and verbose logger - console doesnt prototype
var c = console;
c.l = c.log,
c.e = c.error,
c.v = c.verbose = function() {
if (!myclass || !myclass.verbose) // verbose switch
return;
var args = Array.prototype.slice.call(arguments); // toArray
args.unshift('Verbose:');
c.l.apply(this, args); // log
};
// you can then do
var myclass = new myClass();
myclass.prototype.verbose = false;
// generally these calls would be inside your class
c.v('1 This will NOT log as verbose == false');
c.l('2 This will log');
myclass.verbose = true;
c.v('3 This will log');
I noted that the above use of Array.prototype.unshift.call by nitesh is a better way to add the 'Verbose:' tag.
You can override the default behavior of the console.log function using the below approach, the below example demonstrates to log the line number using the overridden function.
let line = 0;
const log = console.log;
console.log = (...data) => log(`${++line} ===>`, ...data)
console.log(11, 1, 2)
console.log(11, 1, 'some')

Way to save console.count() as an integer?

I am trying to divide 1 by the console.count() every time it is used. However, this code does not work.
var counter = console.count();
console.log(1/counter);
Any suggestions on how I could do this? I tried doing parseInt but no luck.
Way to save console.count() as an integer?
No. console.count() does not return anything, it directly prints to the console, just like console.log().
Simple implementation of console.count:
var count = (function() {
var counter = {};
return function(v) {
return (counter[v] = (counter[v] || 0) + 1);
}
}());
console.log('foo', count('foo'));
console.log('foo', count('foo'));
console.log('bar', count('bar'));
Here is a script that intercepts messages sent to the console.
var counter = 0;
function takeOverConsole(){
var console = window.console
if (!console) return
function intercept(method){
var original = console[method]
console[method] = function(){
var message = Array.prototype.slice.apply(arguments).join(' ')
// do sneaky stuff
if (original.call){
// Do this for normal browsers
original.call(console, message)
}else{
// Do this for IE
original(message)
}
counter++;
}
}
var methods = ['log', 'warn', 'error', 'count']
for (var i = 0; i < methods.length; i++)
intercept(methods[i])
}
To take Felix King's answer a bit further. Here is a more accurate way to intercept and count anything being sent to the console.
You can customize the function a bit and add any methods you want to track and count.
All console methods
I talk about it more here

Access window.console after overwrite

Is it possible to somehow access to console.log after it gets overwritten?
window.console = { log: function (msg) { alert(msg); }, /* etc... */ };
Would be it be possible to regain the original console.log functionality?
You can back up the console before overwriting it.
var oldConsole = window.console;
window.console = { log:function(msg){alert(msg)} //...};
Then you can use the oldConsole variable.
oldConsole.log('test');
If you can't back it up, you can create an iFrame, and then steal the console from there (this may not work in all browsers):
var i = document.createElement('iframe');
i.style.display = 'none';
document.body.appendChild(i);
window.console = i.contentWindow.console;
Demo: http://jsfiddle.net/jcG7E/2
Edit (2017-04-08): This advise is outdated, in Firefox 52 and Chrome 57 console is no longer defined on the window prototype and deleting it will really delete it.
At least with the console object defined by Firefox and Chrome, you can simply delete the overwritten property to restore the original one:
window.console = {};
delete window.console;
window.console.log("This works!");
This works as if the console property were defined on the prototype of the window object - except that it isn't, the browsers are doing some magic here.
It's not possible. Except if whoever has overwritten it has included some code to undo it.
var customLog = {
oriLog: '',
Log: function(){
// create string to display
var displaystring = '';
for (var i = 0, len = arguments.length; i < len; i++) {
displaystring += arguments[i];
if (i + 1 != len)
displaystring += ', ';
}
alert(displaystring);
customLog.oriLog(arguments);
}
}
window.onload = function(){
if (console != null) {
customLog.oriLog = console.log;
console.log = customLog.Log;
}
}

console.log.apply not working in IE9

Looks like I've re-invented the wheel, but somehow this isn't working in Internet Explorer 9, but does in IE6.
function debug()
if(!window.console) {
window.console = { log: function() { /* do something */ } };
}
console.log.apply(console, arguments);
}
Related:
Apply() question for javascript
F12 Debugger tells me that this "object" (console.log) does not support method 'apply'.
Is it not even recognized as a function?
Any other pointers or ideas?
The second part of an answer I gave recently answers this question too. I don't consider this a duplicate of that one so, for convenience, I'll paste it here:
The console object is not part of any standard and is an extension to the Document Object Model. Like other DOM objects, it is considered a host object and is not required to inherit from Object, nor its methods from Function, like native ECMAScript functions and objects do. This is the reason apply and call are undefined on those methods. In IE 9, most DOM objects were improved to inherit from native ECMAScript types. As the developer tools are considered an extension to IE (albeit, a built-in extension), they clearly didn't receive the same improvements as the rest of the DOM.
For what it's worth, you can still use some Function.prototype methods on console methods with a little bind() magic:
var log = Function.prototype.bind.call(console.log, console);
log.apply(console, ["this", "is", "a", "test"]);
//-> "thisisatest"
So you could fix up all the console methods for IE 9 in the same manner:
if (Function.prototype.bind && window.console && typeof console.log == "object"){
[
"log","info","warn","error","assert","dir","clear","profile","profileEnd"
].forEach(function (method) {
console[method] = this.bind(console[method], console);
}, Function.prototype.call);
}
This replaces the "host" functions with native functions that call the "host" functions. You can get it working in Internet Explorer 8 by including the compatibility implementations for Function.prototype.bind and Array.prototype.forEach in your code, or rewriting the above snippet to incorporate the techniques used by those methods.
See also
console.log typeof is "object" instead of "function" - Microsoft Connect (Live account required)
There is also Paul Irish's way of doing it. It is simpler than some of the answers above, but makes log always output an array (even if only one argument was passed in):
// usage: log('inside coolFunc',this,arguments);
// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
window.log = function(){
log.history = log.history || []; // store logs to an array for reference
log.history.push(arguments);
if(this.console){
console.log( Array.prototype.slice.call(arguments) );
}
};
Several of IE's host object functions aren't really JavaScript functions and so don't have apply or call. (alert, for example.)
So you'll have to do it the hard way:
function debug()
var index;
if(!window.console) {
window.console = { log: function() { /* do something */ } };
}
for (index = 0; index < arguments.length; ++index) {
console.log(arguments[index]);
}
}
I came across the same IE trouble and made a routine for it.
It is not as fancy as all the above implementations, but it works in ALL modern browsers.
I tested it with Firefox (Firebug), IE 7,8,9 Chrome and Opera.
It makes use of the evil EVAL, but you will only want to debug in development.
Afterwards you will replace the code with debug = function () {};
So here it is.
Regards, Hans
(function(ns) {
var msgs = [];
// IE compatiblity
function argtoarr (args,from) {
var a = [];
for (var i = from || 0; i<args.length; i++) a.push(args[i]);
return a;
}
function log(arg) {
var params = "", format = "", type , output,
types = {
"number" : "%d",
"object" : "{%o}",
"array" : "[%o]"
};
for (var i=0; i<arg.length; i++) {
params += (params ? "," : "")+"arg["+i+"]";
type = types[toType(arg[i])] || "%s";
if (type === "%d" && parseFloat(arg[i]) == parseInt(arg[i], 10)) type = "%f";
format += (format ? "," : "")+type;
}
// opera does not support string format, so leave it out
output = "console.log("+(window.opera ? "" : "'%f',".replace("%f",format))+"%p);".replace("%p",params);
eval(output);
}
ns.debug = function () {
msgs.push(argtoarr(arguments));
if (console !== undefined) while (msgs.length>0) log(msgs.shift());
}
})(window);
Oops forgot my toType function, here it is.
function toType(obj) {
if (obj === undefined) return "undefined";
if (obj === null) return "null";
var m = obj.constructor;
if (!m) return "window";
m = m.toString().match(/(?:function|\[object)\s*([a-z|A-Z|0-9|_|#]*)/);
return m[1].toLowerCase();
}
Ok, it works when you write it this way:
function debug()
if(!window.console) {
window.console = {};
console.log = function() { /* do something */ };
}
console.log.apply(console, arguments);
}
Odd behaviour... but if you write it this way 'console.log' gets recognized as a function.
The reason I came to this question was that I as trying to 'spicy' the console.log function for a specific module, so I'd have more localized and insightful debug info by playing a bit with the arguments, IE 9 broke it.
#Andy E answer is great and helped me with lots of insight about apply. I just don't take the same approach to support IE9, so my solution is running the console only on "modern browsers" (being that modern means whatever browsers that behave the way I expect =)
var C = function() {
var args = Array.prototype.slice.call(arguments);
var console = window.console;
args[0] = "Module X: "+args[0];
if( typeof console == 'object' && console.log && console.log.apply ){
console.log.apply(console, args);
}
};
Try:
function log(type) {
if (typeof console !== 'undefined' && typeof console.log !== 'undefined' &&
console[type] && Function.prototype.bind) {
var log = Function.prototype.bind.call(console[type], console);
log.apply(console, Array.prototype.slice.call(arguments, 1));
}
}
log('info', 'test', 'pass');
log('error', 'test', 'fail');
Works for log, debug, info, warn, error, group or groupEnd.

javascript error is null or not an object

I am trying to open a window from a php script. But when I click I get this error
Line: 389
Error: 'surgExpressBuildDefaultButton' is null or not an object
Line 389 code is as follow
function setupLayout(i)
{
document.body.onselectstart = function()
{
if (event.srcElement.tagName.search(/input|textarea/i)) return false;
}
setupButtons();
if(window.parent.opener.parent.frames[0].surgExpressBuildDefaultButton)
{
buttonClick(window.parent.opener.parent.frames[0].surgExpressBuildDefaultButton);
}
else
{
layout.buttons.commonButton.fixSelected();
}
for(i = 0; i < da.imgPlus.length; i++)
{
da.imgPlus[i].onclick = clickPlus;
da.imgMinus[i].onclick = clickMinus;
}
for(i = 0; i < da.spnName.length; i++)
{
da.spnName[i].selected = 0;
da.spnName[i].title = da.spnName[i].innerText;
da.spnName[i].onclick = function(){selectCommonProcedure(this);}
da.spnName[i].ondblclick = function(){addCommonProcedure(this);}
da.spnName[i].onmouseout = function(){this.className = (this.selected ? "nSelected" : "nOut");}
da.spnName[i].onmousedown = function(){this.className = "nDown";}
da.spnName[i].onmouseover = da.spnName[i].onmouseup = function(){this.className = "nOver";}
}
da.inpSearch.onkeydown = function(){if(event.keyCode == 13) updateProcedureList();}
da.btnSearch.onclick = da.selSpecialty.onchange = updateProcedureList;
da.btnClose.onclick = function(){window.close();}
da.btnAdd.disable = da.btnSave.disable = CC.Disable;
da.btnAdd.disable(1);
da.btnAdd.onclick = addCommonProcedure;
da.btnSave.disable(1);
da.btnSave.onclick = saveExpress;
}
what could be the problem. Any idea?
It's hard to tell without knowing which of those four dozen lines is line 489, but this jumped out at me:
function setupLayout(i)
{
document.body.onselectstart = function()
{
if (event.srcElement.tagName.search(/input|textarea/i)) return false;
^-- here
You're using event without having declared it (at least, not in the code you quoted). On IE, that'll work because IE makes the event object a property of window (and unless they're shadowed by other declarations, you can access window properties without explicitly qualifying them), but on most other browsers the event object is an argument to the event handler function – and so that code tries to use an undefined value as an object reference, which triggers exactly the error message you're seeing.
The usual idiom for dealing with this discrepancy in browsers (other than using a library like jQuery or Prototype that handle it for you) is this:
document.body.onselectstart = function(event)
{
event = event || window.event;
// ...
};
That idiom declares event it as an argument to the function, but then has it fall back to looking on the window (to support IE).

Categories

Resources