I'm not sure I agree with your framing of the precise terminology ("passing a reference to an object, by value" vs "passing an object by reference"), but it also isn't important. What's important is this:
let a = { foo: "bar" }
let b = { foo: "bar" }
console.log(a === b) // false
and this:
let a = { foo: "bar" }
let b = a
b.foo = "blah"
console.log(a.foo) // "blah"
This is the kind of misunderstanding that causes insidious bugs.
> I'm not sure I agree with your framing of the precise terminology ("passing a reference to an object by value" vs "passing an object by reference")
The distinction is that, if JS truly was pass-by-reference for objects, you could change what the reference was pointing to. But you can't.
I agree with you that objects/references are a stumbling block for new programmers in JS. You have to understand how these things work but there's no explicit concept of a reference, which means it can be tricky to learn.
> you could change what the reference was pointing to
That's only true if you're passing the pointer by reference. That's different from passing the object itself by reference.
I did just look up the C++ semantics and learned something: technically reference-arguments don't have to be implemented by the compiler as pointers, though in practice they mostly are. So in that sense it's technically more correct to say that JS works with object pointers and not references. But we're really getting quite deep into the weeds at that point.
This is the kind of misunderstanding that causes insidious bugs.
That's how all mainstream languages with a GC work, Java, C#, Ruby and Python, it's not particular to JS. And this why why languages like Clojure are nice to work with.
but it also isn't important
It's important if you really want to know why your examples work they way they do.
We're specifically talking about new programmers who haven't used any of those languages, and who are being reared in the JavaScript ecosystem where certain patterns reign that obscure this language behavior. That's what the original discussion was about.
> It's important if you really want to know why your examples work they way they do.
It's really not. Pass-by-reference and pass-a-pointer-by-value are subtly different concepts even in the C++ world, and using terminology that involves the word "pointer" opens up a whole other can of stuff that needs explaining.
It's still pass by value, you are passing the reference of the object as a value.