3

I defined a replacement for console.log which basically adds a global int variable to the beginning of the log.

In the function I'm iterating the arguments array backwards until index equals 1 and move each element by one forwards.

Then I'm adding the global int value at index 1 and change the format string, at index 0, to respect the new argument.

When doing this, console.log uses the new format string and argument but seems to ignore the second – originally first – format argument.

So I created some test functions to compare their output behaviour:

var globalInt = 25;
function log() {
    if (arguments.length > 0 && arguments[0].length > 0) {
        var keys = Object.keys(arguments);

        for (var i = keys.length - 1; i > 0; i--) {
            arguments[parseInt(keys[i]) + 1] = arguments[keys[i]];
        }

        arguments['0'] = '%d: ' + arguments['0'];
        arguments['1'] = globalInt;
    }

    console.log('  %s', JSON.stringify(arguments));
    console.log.apply(console.log, arguments);
}
function log_t1() {
    console.log('  %s', JSON.stringify(arguments));
    console.log.apply(console.log, arguments);
}
function log_t2() {
    if (arguments.length > 0 && arguments[0].length > 0) {
        arguments[0] = '%d: ' + arguments[0];
    }

    console.log('  %s', JSON.stringify(arguments));
    console.log.apply(console.log, arguments);
}

log('test "%s"', 'hello world');

log_t1('%d: test "%s"', globalInt, 'hello world');
log_t2('test "%s"', globalInt, 'hello world');


>> 
  {"0":"%d: test \"%s\"","1":25,"2":"hello world"}
25: test "%s"
  {"0":"%d: test \"%s\"","1":25,"2":"hello world"}
25: test "hello world"
  {"0":"%d: test \"%s\"","1":25,"2":"hello world"}
25: test "hello world"

Comparing those functions, their calls, their outputs and especially the equal JSON prints, I really wonder about the first result.

Can someone see any issue in the code or can confirm this behaviour?

1
  • console.log.apply(console.log, arguments); should be console.log.apply(console, arguments). Commented Sep 7, 2015 at 8:08

1 Answer 1

3

You did not alter the length property of the arguments object. The arguments object is not a simple array, it is something different, and does not alter it's own length property when overindexing.

I suggest you to convert the arguments object to an array first, and favour array methods over loops:

var globalInt = 25;
...
function log() {
    var args = Array.prototype.slice.call(arguments, 0);
    if (args.length > 0 && args[0].length > 0) {
        args = ['%d:  ' + args[0], globalInt].concat(args.slice(1));
    }

    console.log('  %s', JSON.stringify(args));
    console.log.apply(console, args);
}
Sign up to request clarification or add additional context in comments.

5 Comments

Is there a reason your args is a global variable?
Yeah – it should be globally accessible ;) No, seriously, it is meant to be incremented or decreased by other asynchronous tasks in that script. It's just to improve my debugging workflow
Sry, args is local, fixed
Oh sorry, I mistead your comment. The args must not be global, but I want to add a global variable to the array (here 25). I'll edit my question, it's a bit uncliear
You can use global variables there of course. I updated the answer to use one.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.