The answer is quite simple: since ECMAScript is passed by value, not by reference, and your code proves this. (More precisely, this is a send-exchange, which is a certain type of transmission by value.)
See Is JavaScript the default password or language? for more information.
ECMAScript uses pass-by-value, or rather, a special case of pass-by-value, where the passed value is always a pointer. This special case is also sometimes called call sharing, call sharing or shame.
This is the same convention used by Java (for objects), C # (default for reference types), Smalltalk, Python, Ruby, and more or less every object-oriented language ever created.
Note: some types (for example) of Number actually passed directly by value, rather than using a proxy pointer. However, since they are immutable, in this case, there is no observed behavioral difference between passing by value and sharing a call to an object, so you can greatly simplify your mental model by simply considering everything as a call to an object - an exchange. Just interpret these special cases as internal compiler optimizations that you don't need to worry about.
Here is a simple example that you can follow to define an agreement to send arguments to ECMAScript (or any other language after translating it):
function isEcmascriptPassByValue(foo) { foo.push('More precisely, it is call-by-object-sharing!'); foo = 'No, ECMAScript is pass-by-reference.'; return; } var bar = ['Yes, of course, ECMAScript *is* pass-by-value!']; isEcmascriptPassByValue(bar); console.log(bar);
If you are familiar with C #, this is a very good way to understand the differences between passing by value and passing by reference for value types and reference types, since C # supports all 4 combinations: pass-by- value for value types ("traditional pass- by-value "), a rolling value for reference types (call sharing, call-by-object, call sharing differently, as in ECMAScript), pass-by reference for reference types and by-reference for value types.
(In fact, even if you do not know C #, this is not too difficult to do.)
struct MutableCell { public string value; } class Program { static void IsCSharpPassByValue(string[] foo, MutableCell bar, ref string baz, ref MutableCell qux) { foo[0] = "More precisely, for reference types it is call-by-object-sharing, which is a special case of pass-by-value."; foo = new string[] { "C# is not pass-by-reference." }; bar.value = "For value types, it is *not* call-by-sharing."; bar = new MutableCell { value = "And also not pass-by-reference." }; baz = "It also supports pass-by-reference if explicitly requested."; qux = new MutableCell { value = "Pass-by-reference is supported for value types as well." }; } static void Main(string[] args) { var quux = new string[] { "Yes, of course, C# *is* pass-by-value!" }; var corge = new MutableCell { value = "For value types it is pure pass-by-value." }; var grault = "This string will vanish because of pass-by-reference."; var garply = new MutableCell { value = "This string will vanish because of pass-by-reference." }; IsCSharpPassByValue(quux, corge, ref grault, ref garply); Console.WriteLine(quux[0]);