Is the Chrome JavaScript console lazy about evaluating arrays?

I will start with the code:

var s = ["hi"]; console.log(s); s[0] = "bye"; console.log(s); 

Just right? In response, Firebug says:

 ["hi"] ["bye"] 

Great, but the Chrome JavaScript console (7.0.517.41 beta) says:

 ["bye"] ["bye"] 

Am I doing something wrong, or is the Chrome JavaScript console extremely lazy when evaluating my array?

enter image description here

+105
javascript arrays google-chrome logging console
Oct 30 '10 at 5:51
source share
7 answers

Thanks for the comment, i.e. I managed to find an existing unconfirmed Webkit error that explains this problem: https://bugs.webkit.org/show_bug.cgi?id=35801 (EDIT: now fixed!)

There seems to be some debate as to which part of the bugs and whether it is fixed. It seems to me that this is bad behavior. This especially bothered me because, at least in Chrome, this happens when the code is in scripts that execute immediately (before the page loads), even when the console is open, whenever the page refreshes. Calling console.log when the console is not already active only leads to a reference to the object in the queue, and not to the output that the console will contain. Therefore, the array (or any object) will not be evaluated until the console is ready. This is indeed a case of lazy appreciation.

However, there is a simple way to avoid this in code:

 var s = ["hi"]; console.log(s.toString()); s[0] = "bye"; console.log(s.toString()); 

By calling toString, you create a view in memory that will not be modified using the following statements, which the console will read when it is ready. The console output is slightly different from directly traversing an object, but seems acceptable:

 hi bye 
+56
Oct 30 2018-10-10
source share

From Eric's explanation, this is because console.log() is in the queue, and it prints a later value of the array (or object).

There can be 5 solutions:

 1. arr.toString() // not well for [1,[2,3]] as it shows 1,2,3 2. arr.join() // same as above 3. arr.slice(0) // a new array is created, but if arr is [1, 2, arr2, 3] // and arr2 changes, then later value might be shown 4. arr.concat() // a new array is created, but same issue as slice(0) 5. JSON.stringify(arr) // works well as it takes a snapshot of the whole array // or object, and the format shows the exact structure 
+16
07 Oct
source share

You can clone an array using Array#slice :

 console.log(s); // ["bye"], ie incorrect console.log(s.slice()); // ["hi"], ie correct 

A function that you can use instead of console.log that does not have this problem looks like this:

 console.logShallowCopy = function () { function slicedIfArray(arg) { return Array.isArray(arg) ? arg.slice() : arg; } var argsSnapshot = Array.prototype.map.call(arguments, slicedIfArray); return console.log.apply(console, argsSnapshot); }; 

In the case of objects, unfortunately, the best method is to debug using a browser other than WebKit, or to write a complex function for cloning. If you work only with simple objects, where the order of the keys does not matter and there are no functions, you can always:

 console.logSanitizedCopy = function () { var args = Array.prototype.slice.call(arguments); var sanitizedArgs = JSON.parse(JSON.stringify(args)); return console.log.apply(console, sanitizedArgs); }; 

All of these methods are obviously very slow, so even more so than with conventional console.log s, you should disable them after debugging is complete.

+6
Jan 27 2018-11-17T00:
source share

This has been fixed in Webkit, however when using the React Framework this happens for me in some cases, if you have such problems, just use as others suggest:

 console.log(JSON.stringify(the_array)); 
+2
Apr 30 '15 at 0:35
source share

This has already been answered, but I still refuse the answer. I implemented a simple console shell that does not suffer from this problem. Requires jQuery.

It implements only the log , warn and error methods, you will need to add a little more so that it is interchangeable with the regular console .

 var fixedConsole; (function($) { var _freezeOne = function(arg) { if (typeof arg === 'object') { return $.extend(true, {}, arg); } else { return arg; } }; var _freezeAll = function(args) { var frozen = []; for (var i=0; i<args.length; i++) { frozen.push(_freezeOne(args[i])); } return frozen; }; fixedConsole = { log: function() { console.log.apply(console, _freezeAll(arguments)); }, warn: function() { console.warn.apply(console, _freezeAll(arguments)); }, error: function() { console.error.apply(console, _freezeAll(arguments)); } }; })(jQuery); 
+1
Feb 28 '13 at 15:31
source share

It looks like Chrome is replacing the "pre compile" phase with any "s" instance with a pointer to the actual array.

One way: cloning an array, writing the following copy instead:

 var s = ["hi"]; console.log(CloneArray(s)); s[0] = "bye"; console.log(CloneArray(s)); function CloneArray(array) { var clone = new Array(); for (var i = 0; i < array.length; i++) clone[clone.length] = array[i]; return clone; } 
0
Oct. 31 '10 at 14:20
source share

Console.log is not standardized, so in some cases some browsers delay console.log for performance reasons.

However, it is strange that this is happening for something so simple.

0
Apr 01 '19 at 20:24
source share



All Articles