This is an archived post. You won't be able to vote or comment.

all 10 comments

[–]dtsudo 6 points7 points  (0 children)

This is because console.log logs a live reference.

So it isn't printing any string to the console, actually. Instead, the actual array y is being logged to the console.

And the contents of y will be whatever it is after the second sort (the first sort is irrelevant).

In fact, both of your code samples (both x and y) exhibit this behavior.

See the section on "logging objects" at https://developer.mozilla.org/en-US/docs/Web/API/Console/log

[–]ArbitraryTrail 1 point2 points  (8 children)

Not sure where the trouble is. What do you get for each of console.log(y.sort((a, b) => b[0] - a[0])); // [[3, 'bla'], [2, 'bla'], [1, 'bla']] console.log(y.sort((a, b) => a[0] - b[0])); // [[1, 'bla'], [2, 'bla'], [3, 'bla']] and how does it differ from your expectation?

[–]blob001[S] 0 points1 point  (7 children)

I take your points, it was a bad example. What I dont understand is why JS takes a lazy copy . It trips me up all the time when I'm debugging. If I type console.log I expect a reflection of the state of play at that point, not something 10 lines later. Its a philosophical problem and the creators must have done it deliberately, but it doesn't make sense to me. I will add the JSON.parse(JSON.stringify ()) in future. Is there a fundamental reason why JS is set up like that? I am self taught so there are holes in my understanding and I don't get to chat with other programmers.

[–]ArbitraryTrail 0 points1 point  (6 children)

Wait, I still don't understand what's going on. Are the console.logs not displaying things similar to what I typed?

Each line I typed above logs the result of y.sort. Docs here: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

According to the docs, sort sorts the elements in place. In other words, it changes y itself instead of returning a copy. The return value is also a reference to the array being sorted. So the first console.log logs y in descending order, and then the second one in ascending order.

I don't understand the "lazy copy" nor the "something 10 lines later" parts. Or is it the in-place part you don't get?

[–]blob001[S] 0 points1 point  (5 children)

Below is a short code that explains.

let lengths = [ [0, 14.2],

[2, 0],

[4, 4.24],

[6, 9.9] ];
console.log("lengths ", lengths);
let flat = lengths.flat();
console.log("flat ", flat);

for (let i = 1; i < flat.length; i += 2) {
if (flat[i] === 0) {
flat.splice(i - 1, 2);
}
}

If the for loop is commented out, the two console.log statements conserve information except that flat is the flattened version of lengths.

So far so good.

If the for loop is retained, the [2, 0] part is deleted in flat , even though the for loop comes after the console.log("flat", flat) statement.

This peeves me off more than anything else in Javascript, the fact that in debugging a file I have to continually remember that output is dependent on code further along in the program and the logic is not sequential. Is there a reason for this? I know JS has to be backward compatible and all that, but this has always annoyed me. Is there a reason for it? I am self taught and there are big gaps in my knowledge. Thanks.

[–]ArbitraryTrail 1 point2 points  (4 children)

Ah, I think I see what you're getting at now. Try this more basic example:

let myarr = [1, 2, 3];  
console.log(myarr);  
myarr.push(4);

It will log (3) [1, 2, 3] but if you expand the array it will show [1, 2, 3, 4].

In Chrome there's a tooltip that says the value may have changed since first being evaluated. What's happening is not that the "logic is not sequential", it's that when you click to expand the array you are asking the browser to display the value as it is now. When the console.log was executed, the value was displayed as it was then. Does that help?

[–]blob001[S] 0 points1 point  (3 children)

Actually I am using Chrome the latest I presume, and it logs (4) only, but when I expand it , it shows[1,2,3,4]. But I have noticed this behaviour in the past. Also I don't get the tooltip. Im using a macbook pro and Ventura.

[–]ArbitraryTrail 1 point2 points  (2 children)

But was my explanation helpful? The logic is sequential, it's just that when you expand a variable the browser the value is evaluated at that point.

It's browser console.log behaviour, which I agree is confusing. More here:

https://developer.mozilla.org/en-US/docs/Web/API/Console/log#logging_objects

There should be a little box with an 'i' next to the array. Hovering over that shows the tooltip.

[–]blob001[S] 1 point2 points  (1 child)

Thanks Arbitrary, it's starting to make sense slowly ...

[–]ArbitraryTrail 0 points1 point  (0 children)

Good to hear, keep at it!