DEV Community

Cover image for TIL - Spread and Copying Objects in Javascript

TIL - Spread and Copying Objects in Javascript

Branden Kim on August 11, 2020

Background This is a part of a series of writing a tutorial of what I learn everyday. I try to learn something new related to CS and pro...
Collapse
 
pentacular profile image
pentacular • Edited

In Javascript, all primitive types are assigned and passed by value, but all objects are assigned and passed by reference.

Objects are not assigned and passed by reference.

Consider the following example.

const a = { name: 'a' };

const foo = (v) => {
  v = { name: 'v' };
}

console.log(JSON.stringify(a));

If objects were assigned and passed by reference then the output would be { "name":"v" } since under pass-by-reference semantics, the parameter and the argument would refer to the same thing.

The output is { "name":"a" } because Javascript does not have pass-by-reference semantics.

a is passed by value.

The confusion comes from thinking that the properties of an object are part of the value of the object, which is the case in C++, but not in Javascript.

In Javascript the value of an object allows you to access the properties associated with that object, and it is these properties that may be mutable.

And, naturally, if you pass the value of an object to something, that something can now access and potentially change those properties.

They are passed by value, just like the other primitive values.

Collapse
 
canmingir profile image
Can Mingir

"They are passed by value, just like the other primitive values." That is incorrect.

JavaScript has pass-by-reference, only difference to C++ is it is pass by "copy of reference". Do not alter terminology

Collapse
 
pentacular profile image
pentacular

I'm not the one altering terminology here.

Passing a copy of a reference wouldn't be pass-by-reference, in any case.

en.wikipedia.org/wiki/Evaluation_s...

"Call by reference (or pass by reference) is an evaluation strategy where a function receives an implicit reference to a variable used as argument, rather than a copy of its value."

Your peculiar "copy-of-a-reference" notion fails to satisfy this requirement.

"This typically means that the function can modify (i.e., assign to) the variable used as argument—something that will be seen by its caller."

And you may note that Javascript doesn't permit this foo(a) cannot change the value of the variable a for the caller.

Next you may review the ecmascript standard.

ecma-international.org/publication...

See: 12.3.6.2 Runtime Semantics: EvaluateCall

And note that it passes values, not references (or even copies of references).

Javascript does have references -- For example in delete a.b; a.b is a reference -- but they are not references to objects; they are references to properties.

Thread Thread
 
canmingir profile image
Can Mingir • Edited

I am glad that you put some links, usually, so much opinions going on in discussions.

ECMA also says value of object reference in your link.

"Object references are values"
developer.mozilla.org/en-US/docs/W...

Good explanation here as well:
stackoverflow.com/questions/131044...

Another:
w3schools.com/js/js_function_param...

Agreeing on object property part, but calling function by value of object is not true.

Thread Thread
 
pentacular profile image
pentacular

ECMA also says value of object reference in your link.

ECMA never mentions 'object references' anywhere.

It mentions 'object values', and explains how they allow you to access the properties associated with that object value.

See '7.3 Operations on Objects' to understand how object values are used to access object properties (and note the complete lack of 'object references').

"Object references are values"

Mozilla is describing how their implementation works, not specifying the language.

Mozilla implements objects using a value that refers to a structure somewhere, and they call this value an 'object reference' because it is a value that refers to an object.

This has nothing to do with how the language is specified, or with pass-by-reference.

It is passing a value (which happens to refer to some kind of object structure in their implementation) as a value.

Good explanation here as well:
stackoverflow.com/questions/131044...

Yes -- you can break the comments down into two categories.

  1. Those pointing out that javascript passes-by-value.
  2. Those pointing out that javascript passes-by-value, but confusing this by introducing an alien notion of 'object reference' values to allow them to understand this in terms of a language like C++.

What you may note is consistent is that they all agree that javascript passes-by-value. :)

Another

"Arguments are Passed by Value
The parameters, in a function call, are the function's arguments.
JavaScript arguments are passed by value: The function only gets to know the values, not the argument's locations.
If a function changes an argument's value, it does not change the parameter's original value."

They got this bit right. :)

"Objects are Passed by Reference
In JavaScript, object references are values.
Because of this, objects will behave like they are passed by reference:
If a function changes an object property, it changes the original value."

The only way to resolve these two assertions is that javascript is, again, pass-by-value.

They're just confusing the ability to change a property via an object value with meaning that there's somehow a magical reference value to that object.

It's much simpler than that -- let's go back to the standard.

7.3.2 Get ( O, P )

Get(objectValue, propertyKey)

foo.bar is just equivalent to calling Get with the object value and a property key.

No object reference value nonsense -- just simple values.

Thread Thread
 
canmingir profile image
Can Mingir

Incorrect, and I don't understand why you are complicating this stuff.

If you are not sending copy of value, you are sending its reference.