views:

246

answers:

4

Hi,

I'm using firebug and have some statements like:

console.log("...");

in my page. In IE8 (probably earlier versions too) I get script errors saying 'console' is undefined. I tried putting this at the top of my page:

<script type="text/javascript">
    if (!console) console = {log: function() {}};
</script>

still I get the errors. Any way to get rid of the errors?

Thanks

+5  A: 

Try

if (!window.console) console = ...

An undefined variable cannot be referred directly. However, all global variables are attributes of the same name of the global context (window in case of browsers), and accessing an undefined attribute is fine.

KennyTM
Thank you that works.
+1  A: 

In my scripts, I either use the shorthand:

window.console && console.log(...) // only log if the function exists

or, if it's not possible or feasible to edit every console.log line, I create a fake console:

// check to see if console exists. If not, create an empty object for it,
// then create and empty logging function which does nothing. 
//
// REMEMBER: put this before any other console.log calls
!window.console && (window.console = {} && window.console.log = function () {});
slightlymore
+2  A: 

Another alternative is the typeof operator:

if (typeof console == "undefined") {
    this.console = {log: function() {}};
}

Yet another alternative is to use a logging library, such as my own log4javascript.

Tim Down
It would be a good idea to change undeclared assignment into a proper declaration, though.
kangax
Do you mean using `var`? That would only confuse things here. Or do you mean assigning to `window.console` rather than `console`?
Tim Down
Using `var`. Why would it confuse things here?
kangax
Putting a `var` inside an `if` block is confusing and looks like a mistake. It also changes the nature of `console` regardless of whether the `if` block is executed because a variable is always declared. I agree that implicitly assigning to a global variable as I am here also looks like a mistake, but it only changes behaviour when `console` is undefined. Neither is ideal.
Tim Down
The problem with omitting `var` when assigning to `console` — as in this example — is not even so much that it looks like a mistake. First of all, IE DOM has an unfortunate peculiarity when undeclared assignment throws error if identifier is the same as id of one of the elements in the document. Second — and more importantly — in ES5 strict mode, undecl. assignment is actually a deliberate ReferenceError. Given that strict mode is more or less a future direction of a language, for compatibility reasons, undecl. assignments are best avoided. But if you must, `this.console=..` is an alt. option.
kangax
Re the IE DOM global scope pollution insanity, I am aware of it but we already know console is undefined, at least at the point that code is run. The ES5 point is a good one: I haven't started thinking in terms of ES5 all the time yet. For myself, I wouldn't consider using that code anyway and instead create a wrapper around console.
Tim Down
Hello downvoter? Please explain yourself.
Tim Down
Hey Tim. I see you changed `console = ...` to `this.console = ...`. Excellent, I changed my vote.
kangax
Ah, right, thanks. Wondered whether it might've been you. I was waiting till we'd finished discussing before changing it; the ES5 point had clinched it, but I wasn't sure if you were still advocating `var console` over `this.console`.
Tim Down
Well I personally use `var console = ...` and `this.console = ...` interchangeably. Let me also point out that variable declaration does not change the nature of existing variable (or property of variable object, to be precise). If `console` is already a global property, `var console` executed in global code is essentially a no-op. That's why `if (typeof console == 'undefined') { var console = ... }` does not change `console` at all if it's already declared. Alternative version would be `var console; if (typeof console == 'undefined') { console = .. }`, but this could look confusing as well :)
kangax
OK. You're right. Obviously using `var console` would change the nature of a `console` property that was added to the global object later on, but that wasn't the point we were previously discussing. Thanks.
Tim Down
A: 

You can use console.log(...) directly in Firefox but not in IEs. In IEs you have to use window.console.

Mohit Kumar
console.log and window.console.log refer to the same function in any browser which is even remotely conformant with ECMAscript. It is good practice to use the latter to avoid a local variable accidentally shadowing the global console object, but that has absolutely nothing to do with the choice of browser. console.log works fine in IE8, and AFAIK there is no logging capability at all in IE6/7.
Tgr