tags:

views:

60

answers:

5

UPDATE: Here's my solution (inspired by accepted answer):

function log(msg, values) {
         if(config.log == true){
         msg = [msg];
         var args = msg.concat(values);
         console.log.apply( this, args );
         }
     }

UPDATE2: Even better solution:

 function log(msg) {
     if(config.log == true){
     msg = [msg];
     var values = Array.prototype.slice.call(arguments, 1);
     var args = msg.concat(values);
     console.log.apply( console, args );
     }
 }

You can call this version like so:

log("Hi my name is %s, and I like %s", "Dave", "Javascript");

Here's the original question:

console.log takes a string and replaces tokens with values, for example:

console.log("My name is %s, and I like %", 'Dave', 'Javascript')

would print:

My name is Dave, and I like Javascript

I'd like to wrap this inside a method like so:

function log(msg, values) {
  if(config.log == true){
    console.log(msg, values);
   }
 }

The 'values' arg might be a single value or several optional args. How can I accomplish this?

If I call it like so:

 log("My name is %s, and I like %s", "Dave", "Javascript");

I get this (it doesn't recognize "Javascript" as a 3rd argument):

 My name is Dave, and I like %s

If I call this:

 log("My name is %s, and I like %s", ["Dave", "Javascript"]);

then it treats the second arg as an array (it doesn't expand to multiple args). What trick am I missing to get it to expand the optional args?

+2  A: 

You're looking for the arguments identifier, which is an array-like object (but not an actual array) containing all of the arguments that were passed to the function.

In your example, you can get an array containing all of the arguments after the first one like this:

var values = Array.prototype.slice.call(arguments, 1);
SLaks
thanks, very handy to know about the arguments identifer and this will be very useful for future.
Dave Paroulek
A: 

EDIT: I was surprised this didn't work so I went back, looking at all the above.

Dave, If you want to call it like this:

log("My name is %s, and I like %s", 'Dave', 'Javascript');

Then the simplest solution is this:

function log() {
    if(console.log !== null){
        console.log.apply(console,arguments);
    }
}

Oh, and console.log == true didn't work in either FF or Chrome for me. Only console.log != null worked. And nothing worked in IE7, go figure.

ORIGINAL(bad) answer:

Javascript has a special 'arguments' variable that does exactly what you want.

   function log(msg, arguments) {
       if(config.log == true){
         console.log(msg, arguments);
       }
   }
Matthew Smith
This will not do what he wants.
SLaks
A: 
if(!window.log && console && console.log) window.log = console.log;
jAndy
+2  A: 

Though this isn't jQuery related, I can try answer it anyway :)

Following might work (untested):

function log(msg, values) {
  if(typeof config.log != 'undefined' ) {
    if( typeof values != 'Array' ) {
      values = [values];
    }
    values.unshift( msg );
    console.log.apply( this, values );
  }
}
azatoth
Thanks. 'apply' was exactly what I needed. I updated the question with my solution.
Dave Paroulek
Though this works a charm in FF, just FYI this will not work in Chrome, as it will cause an `Uncaught TypeError: Illegal invocation` due to the `apply` method for some reason
mVChr
The Chrome failure is presumably because you're passing the `log` function's `this` (which will probably be the `window` object) as the `thisArg`. The `thisArg` for `console.log` should clearly be `console`.
bobince
This doesn't work in Chrome as the output will be `My name is Array, and I like %s`... see my answer for a function that will work in both browsers.
mVChr
Just tested and it works in Chrome if you use `console.log.apply( console, args );` as pointed out by bobince.
Dave Paroulek
@dave and bob: Yea, that makes perfect sense. as `console` is an object we need to execute the function with that object as `this`. (Perhaps I should test code before answering :))
azatoth
+1  A: 

@azatoth created an intelligent answer, but since won't work in Chrome I would use simple string concatenation instead:

function log(msg, values) {

    if (undefined != console) {
        var newArg = '';
        var newMsg = msg.split('%s');

        if (undefined != values) {
            for (i=0; i < (newMsg.length-1); i++) {
                newArg += newMsg[i] + values[i];
            }
        } else {
            newArg = newMsg[0];
        }

        console.log( newArg );
    }

}
mVChr