Reputation: 19979
I have lived under the assumption that there are primitive types and reference types in Javascript. On a day-to-day basis, I've never had this impact me but I was just starting to a lot more JS and wanted to update my 'thinking'. In other words, I would have betted $20 that the following would return 68
var my_obj = {};
var tmp_obj = {};
tmp_obj.my_int = 38;
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int = 68;
alert('68 means reference, 38 means primitve: ' + my_obj.tmp_val);
but it returns 38.
Are all instances of numbers primitive types even if they exist in the context of a reference type? If y, I'm really surprised and find that odd behavior(and would be out $20). Or is my example not demonstrating what I think it is?
thx in advance
UPDATE #1
Wow, thx for all the answers. Here's a slight change which helps me a lot in understaning:
var my_obj={};
var tmp_obj={};
var my_obj_2=tmp_obj;
tmp_obj.my_int=38;
my_obj.tmp_val=tmp_obj.my_int;
tmp_obj.my_int=68
alert('68 means reference, 38 means primitve: ' + my_obj.tmp_val); // 38
alert('68 means reference, 38 means primitve: ' + my_obj_2.my_int); // 68
my_obj_2.my_int=78;
alert(tmp_obj.my_int); // tmp_obj is now 78 ie two way
Upvotes: 12
Views: 2684
Reputation: 71939
I believe there are two key things to understand here:
Considering this code to demonstrate the first point:
var a = 10,
b = a,
c = {foo : 20}
d = c.foo;
b = 20;
d = 30;
a; // 10;
c.foo; // 20;
So, you have "slots" (variables or properties) holding primitive values, not references. Changing the value in one of those slots won't affect the others.
Considering the second point:
var a = {foo: true},
b = a;
b.foo; // true
b.foo = false;
a.foo; // false;
b = {bar: false};
a; // {foo: false}
Variable a
contains an object, and b
is initially a reference to the same object. Assigning to b.foo
affects a
, since b
and a
are pointing to the exact same object. However, those references are just like any other value stored in a given slot: when you assign something else to the slot, the reference just gets replaced with a different value. So assigning to b
doesn't affect a
.
Upvotes: 2
Reputation: 362107
If I may use a Java-like syntax, it appears you expected the code to behave like this, where there is an integer object that has its value mutated.
tmp_obj.my_int = new Integer(38);
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int.setValue(68);
Since it doesn't print 68
you conclude that integers must be a primitive type not a reference type. That doesn't necessarily follow, though. Consider this alternate interpretation:
tmp_obj.my_int = new Integer(38);
my_obj.tmp_val = tmp_obj.my_int;
tmp_obj.my_int = new Integer(68);
Here integers are reference types but my_obj.tmp_val
will still contain the value 38
, because assigning to an integer means overwriting references.
You can think of integers as being immutable objects. JavaScript does a very good job of presenting a unified everything-is-an-object view, so this is a better interpretation of the results than "integers are primitive types".
Upvotes: 6
Reputation: 700800
Yes, values like numbers and strings work like primitive values. They are immutable. Assigning a new value to a variable replaces the old value, it doesn't change the value that's there.
Example:
var x = 42;
var y = x; // y == 42
x = 1337; // this puts a new value in x, it doesn't change 42 to be 1337
alert(y); // it's still 42
The same works for strings:
var x = "42";
var y = x; // y == "42"
x = "1337"; // this puts a new string in x, it doesn't change "42" to be "1337"
alert(y); // it's still "42"
Also if you use object properties;
var o = {};
o.x = 42;
o.y = o.x; // o.y == 42
o.x = 1337; // this puts a new value in o.x, it doesn't change 42 to be 1337
alert(o.y); // it's still 42
How a value acts only depends on its type, not wether it's stored in a regular variable or in a property in an object.
Even if strings are implemented as an object internally, it's immutable and works as a value. Copying a string may copy a reference to an object, but the effect is that you get a separate copy, because nothing can change the string value itself.
Upvotes: 4
Reputation: 665455
I have lived under the assumption that there are primitive types and reference types in Javascript.
That's true. The only reference values are objects, though; primitive values are not mutable.
Are all instances of numbers primitive types even if they exist in the context of a reference type?
Yes. Their context is not relevant.
Upvotes: 3
Reputation: 52047
You example would work as expected if you had
my_obj = tmp_obj;
Then, all the properties would point to the same reference since there would only be one object.
But when you write
my_obj.tmp_val = tmp_obj.my_int;
then my_obj.tmp_val
will take the value that's stored in tmp_obj.my_int
but that doesn't create a new reference between the 2 objects.
Upvotes: 7