5

I have this bit of code:

            var has_logger = (window.console && window.console.log);
            if (has_logger) {
                window.console.log(data);
            }

has_logger, instead of being a boolean value, is actually initialised to a function object ( function log() { [native code] } )

My questions:

  • There is no need to test for the console.log in modern browsers, correct?

  • What is the proper way to initialize has_logger to a boolean value instead of a function object?

mplungjan
  • 134,906
  • 25
  • 152
  • 209
Anthony Kong
  • 29,857
  • 33
  • 139
  • 244

6 Answers6

4

If Firebug is not enabled, Firefox will throw an error if you don't check.

var has_logger = !!(window.console && window.console.log);

will always be Boolean.

Amadan
  • 169,219
  • 18
  • 195
  • 256
  • More understandable than `var has_logger=(window.console && window.console.log)?true:false;// force boolean` ? - terser, for sure. – mplungjan May 19 '11 at 06:05
  • @mplungjan: Oh, you don't want to (re)start the whole `!!` vs. ternary debate... ;-) – T.J. Crowder May 19 '11 at 06:08
  • @TJC ah, there is such a thing? How do I find it? "ternary versus" ? – mplungjan May 19 '11 at 06:11
  • 1
    Why assume window has been defined? `!!(window && ...);` – RobG May 19 '11 at 06:36
  • Heh, I was answering the literal questions: do you have to test, and how to make `has_logger` boolean. – Amadan May 19 '11 at 07:55
  • Since I found this today, @RobG, if window isn't defined then there's nothing to attach the DOM and the website won't render. Window should exist in a browser environment - it's supported by all major browsers even though it's not part of the standard. If you're not using a browser (ie: server side / node), then you would want to test for window as well. http://www.w3schools.com/jsref/obj_window.asp – John O'Connor Oct 26 '12 at 16:24
  • @JohnO'Connor—there is nothing in the OP about the DOM or that is specific to a browser. The HTML5 specification (which is not a standard but is all we're going to get) includes a [`window` object](http://www.w3.org/TR/html5/browsers.html#the-window-object). Interestingly, it isn't included in the "[DOM Living Standard](http://dom.spec.whatwg.org/)" but does get a mention in the "[HTML Living Standard](http://dom.spec.whatwg.org/)", which seems back–to–front to me. – RobG Oct 28 '12 at 23:17
  • Agreed on the back-to-front ordering of the standards - what a PITA. I was addressing the first bullet point - there really is no need to test for window in modern browsers since it's supported universally. OP did mention browsers in the first bullet. My point about the DOM was with regard to timing - specifically, the main document is contained by window, so you're guaranteed to have window if you have document. No need to worry about window not yet being initialized. – John O'Connor Oct 28 '12 at 23:33
4

Yes, that's a perfectly fine way to test, and yes you do have to test. Note that your has_logger variable actually ends up with a reference to the function, so you could turn it into a boolean using the double-bang as Amadan said.

Beware of IE9's odd behavior around console.log, though.

If you want your code to work in other JavaScript environments than browsers, though, you might use this:

has_logger = typeof console === "object" && console.log;

You can safely test the type of a free reference even if it's not defined. That will work in browsers (where you have window) and other environments (where you don't).

Community
  • 1
  • 1
T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • Thanks very much for the great answers. All answers to my question are of top quality I wish I can give a tick to all of them. So I will give it for the first answer. Have my upvote. – Anthony Kong May 19 '11 at 16:08
3

Often times when the console.log functionality doesn't exist in other browsers I still want to output the results somewhere. Instead of having an if statement each time I want to write to the log I've created the following bit of javascript that adds a console.log method to the window object when it doesn't already exist. This means wherever in my code I want to use console.log I can do so without worrying about it breaking in other browsers.

(function () {
        if (typeof window.console !== "object")
            window.console = {
                log: function (message) {
                    // Write the message somewhere in browsers that don't support console.log
                }
            };
    } ());

Since I use jQuery I use the following to write each message to a div.

$(function () {

    (function () {
        if (typeof window.console !== "object")
            window.console = {
                log: function (message) {
                    $('<div>' + message + '</div>').appendTo('#consoleArea');
                }
            };
        } ());
});
Paul Mendoza
  • 5,494
  • 9
  • 47
  • 80
2

Firefox 3.6 and earlier does not have a window.console. I don't know that you'd count that as modern.

For your second question, the && operator in JavaScript doesn't return a boolean value; it returns either its left-hand-side expression (if it's falsy) or its right-hand-side expression (if the left-hand-side is not falsy). If you really do want a boolean for some reason, use !!(whatever-value).

Boris Zbarsky
  • 33,680
  • 5
  • 48
  • 54
  • Thanks very much for the great answers. All answers to my question are of top quality I wish I can give a tick to all of them. So I will give it to the first answer. Have my upvote. – Anthony Kong May 19 '11 at 16:08
2

All will give you a bool:

var has_logger = (window.console && window.console.log) ? true : false;
var has_logger = new Boolean(window.console && window.console.log);
var has_logger = !!(window.console && window.console.log);
gaRex
  • 4,032
  • 21
  • 36
  • Great answer! Since all answers to my question are of top quality I really wish I can give a tick to all of them. So I will give it to the first answer. Have my upvote. – Anthony Kong May 19 '11 at 16:09
1

Here's what I've come up with lately in an attempt to be really fully bulletproof... I hope you folks will let me know if I've missed something. It seems to guard against reference errors and be false unless log is a function. If someone's attached some other function to window.console.log that throws an error there's just nothing one can do about that.

var hasLog = !!("console" in window && 
                window.console && 
                "log" in window.console && 
                window.console.log && 
                typeof window.console.log == 'function')

I came up with this after reading https://stackoverflow.com/a/3390426/1172174

Community
  • 1
  • 1
Gus
  • 6,132
  • 6
  • 32
  • 53