Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

if two vars share the same reference to a non-primitive type why doesn't this code work [duplicate]

Tags:

javascript

I am currently dealing with understanding how values are assigned and passed around in Javascript. Primitive type's values are passed by value-copy, and object value types are passed by reference-copy.

If that is the case then why does this line of code not cause "yourAddress" variable to change the property of "street" to "321 cba street"?

var myAddress = {
  street: "123 abc st",
};
var yourAddress = myAddress;
myAddress = { street: "321 cba street" }; // doesn't change the val
myAddress.street = "321 cba street"; // doesn't change the val
console.log(yourAddress.street);

Why doesn't re-assigning the variable, or modifying the property name affect also the output of yourAddress.street since it has the same reference as myAddress.

Is the reason for this hoisting or am I not understanding something here internally with JS?

The version of this code that would work is this but why?

var myAddress = {
  street: "123 abc st",
};
myAddress = { street: "321 cba street" }; // doesn't change the val
myAddress.street = "321 cba street"; // doesn't change the val

var yourAddress = myAddress;

console.log(yourAddress.street);
like image 957
Abdul Nasir Avatar asked Jan 16 '20 15:01

Abdul Nasir


People also ask

What happens when you assign a variable of primitive data type to another variable of same type?

When you assign a value to a primitive variable with an equality sign, the value on the right side is copied to the memory location indicated by the name of the variable. For example, the statement int first = 10 reserves a location called first for the variable, and then copies the value 10 into it.

Can Boolean values can be cast into any other primitive type?

2.4. In addition, because every character corresponds to a number in the Unicode encoding, char types can be converted to and from the integer and floating-point types. In fact, boolean is the only primitive type that cannot be converted to or from another primitive type in Java.

Is Double A non-primitive data type?

Primitive data types specify the size and type of variable values. They are the building blocks of data manipulation and cannot be further divided into simpler data types. There are 8 types of Primitive data types in Java – Boolean, char, byte, int, short, long, float, and double.

How does a variable of a primitive type differ from a reference variable?

The basic difference is that primitive variables store the actual values, whereas reference variables store the addresses of the objects they refer to.


2 Answers

myAddress = { street: "321 cba street" }; // doesn't change the val

Yes, because this reassigns myAddress to point to a totally different object from yourAddress, so of course changes made thereafter to myAddress won't reflect to yourAddress. It's as if yourAddress = myAddress never happened.

Going back to the beginning of the program:

var myAddress = {
  street: "123 abc st",
};
var yourAddress = myAddress;

At this point, here's what the vars point to:

.------------------.
| object in memory | <------------ myAddress
`------------------`
         ^
         +------------------------ yourAddress

Then after the next line executes:

myAddress = { street: "321 cba street" }; // doesn't change the val

we have:

.------------------.
| object in memory | <------------ myAddress
`------------------`
.------------------.
| object in memory | <------------ yourAddress
`------------------`

These are two totally distinct objects being referenced by separate variables.

Remove the reassignment to myAddress and you'll see the change to the single object as accessed by multiple variables as you expect.

var myAddress = {street: "123 abc st"};
var yourAddress = myAddress;
myAddress.street = "321 cba street";
console.log(yourAddress.street, myAddress.street);

This situation (two references to one object in memory) is fundamentally the same as making a function call with an object parameter. A new variable is created on the function stack, but it's not a copy of the object; it's just a reference to the same underlying data.

var fn = param => {
  param.street = 42;
};

var myAddress = {street: "123 abc st"};
fn(myAddress);
console.log(myAddress.street);
like image 101
ggorlen Avatar answered Oct 15 '22 08:10

ggorlen


As you already understand, non-primitive variables only hold a reference. This reference works just like any primitive type (only the reference, not the object): it can be copied, and reassigned without changing the other reference. So, in this code, foo.bar will still be 2:

let foo = {bar: 2};
let bar = foo;
bar = {bar: 5};
console.log(foo.bar);

The reference is copied just like any primitive type; the difference is that you can change an object through a reference.

like image 32
CoderCharmander Avatar answered Oct 15 '22 08:10

CoderCharmander