It’s not unusual to want to write a cross-browser logging function akin to Firebug’s console.log(). The approach that you would expect to work could quite plausibly be this:
function log() {
if(console) {
console.log.apply(this,arguments);
}
}
We invoke the function with apply here so that implementations that can take multiple arguments receive them.
However, this function breaks Safari (at least it does on version 3.1.2) – causing a helpful message TypeError: type error. At the moment, Safari’s console.log only takes one argument, so a way to fix the above function is as follows:
function log(s) {
if(console) {
if(navigator.userAgent.toLowerCase().indexOf("applewebkit") != -1) {
console.log(s);
} else {
console.log.apply(this,arguments);
}
}
}
Quite why this is a problem is not clear to me. I did try to submit a bug report to Apple, but arrived at this page instead:

I would appreciate it if someone would try and recreate the problem in Webkit – I’ve at least seen their bug tracker online.

7 Comments
How about:
# function log() {
# if(console) {
# console.log(arguments);
# }
# }
That should work just as well without needing to use apply, or am I missing something?
Hey, that post leaves me feeling fooislh. Kudos to you!
Having given it some more thought, I guess the difference is that without using apply the arguments would be passed as an array which isn’t quite as useful but should still work.
I find Safari’s behaviour here quite weird. Normally, you’d expect it to just ignore additional arguments. It’s as if it’s saying “if (arguments.length > 2) throw exception”. An explicit check like that is the only way it could be doing something as annoying as this! That, or it’s some native thing where the error is actually coming from calling a C/C++ function with the wrong number of args.
I often use this idiom on the fly, so I wanted a simpler bit of code that I can write quickly without having to look up. I think the following will achieve the same effect as above with less finger typing:
if (console && console.firebug) { console.log.apply(this, arguments); }
If you just change:
console.log.apply(this, arguments)
to:
console.log.apply(console, arguments)
Everything should work.
And multiple arguments works in the newer WebKit (not Safari 3).
Top stuff Tim, thanks.
In fact, even Safari 5.1.2 (OSX Lion) still behaves the same. I was glad to find this page as I was unable to see any error in my code