DEV Community

Discussion on: Like `console.log` But Better

Collapse
 
spiralx profile image
James Skinner

It does print the true value, if you log a variable and then reassign it later the console log will show the original value. However properties of that variable may have changed since the log statement was made and the console only evaluates properties when you expand an object in the console, so you get the current values instead of those at the time you called console.log.

If you're interested in shallow properties you can just log { ...obj } instead of obj, or if you want the entire tree of properties you can use something like Lodash's cloneDeep to get a copy of the object and all nested properties.

npmjs.com/package/lodash.clonedeep

Thread Thread
 
bernardbaker profile image
Bernard Baker

Could you run this code in a web debugger?

var myVar = {a: true};
var myVar2 = {};
myVar2.b = myVar; // {b: {a: true})
myVar.a = false;
console.log(myVar2); // === {b: {a:false}}

What output do you get?

Thread Thread
 
spiralx profile image
James Skinner

{b: {a:false}}, which is as expected.

Thread Thread
 
bernardbaker profile image
Bernard Baker

Must have been the wrong example.

Thread Thread
 
bernardbaker profile image
Bernard Baker

Try this one.

let data = [1,2,3,4,5,6,7]; // length === 7
console.dir(data); // length === 7. But the actual length is 6.
let obj = data.pop();
Thread Thread
 
spiralx profile image
James Skinner

The console correctly shows the variable data. As I said, it doesn't enumerate its properties until you click the arrow to expand data, at which point it's correct. It's not necessarily intuitive that it works this way, but it does so because this way because if you try and preserve an exact i.e. deep copy of data you a) start racking up memory costs - from console.dir(window) you can easily go a dozen levels down into nested objects, and b) start having to keep track of circular references to ensure your copying process doesn't get stuck in an infinite loop - imagine adding a line before the console log with data.push(data). Instead when you click the arrow to expand a level it just has to do a shallow copy of the variable you're expanding at that time, no copying or checking for circular references required.

If you want to show data at the point before the pop(), then call console.log([ ...data ]) instead. It still won't show you the previous state if the objects within the array have changed properties, but it will show you all seven items. And if you're dealing with simple objects JSON.stringify is handy, because it only supports simple data types where recursion is impossible.

Thread Thread
 
bernardbaker profile image
Bernard Baker

Thanks for explaining that to me.

Thread Thread
 
spiralx profile image
James Skinner

No problem!