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?
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);
}