Reputation: 291
The snippet below exposes the doubt
var foo = 'something'
var baz = 'other thing'
var obj = {
prop1 : 'my prop',
prop2 : foo, //referencing external variable
prop3 : baz //referencing external variable
}
// here we get the expected obj to be printed
console.log(obj)
// now I change one of the initial variable
foo = 'changed'
// here we get the sabe print as the first, that is the ~problem~
console.log(obj)
So, how to print 'changed' on prop2 without reassign obj.prop2 = foo
Upvotes: 7
Views: 7261
Reputation: 6818
Since JavaScript is pass by value instead of pass by reference you cannot override the previous value by assigning it directly to the variable.
You can though make an object of it, and change a property of the object like this:
var foo = {value: 'something'}
var baz = 'other thing'
var obj = {
prop1 : 'my prop',
prop2 : foo, //referencing external variable
prop3 : baz //referencing external variable
}
console.log(obj)
foo.value = 'changed'
console.log(obj)
Upvotes: 12
Reputation: 22766
You're only getting the values of the variables, not linking the variables themselves:
var foo = 'something'
var baz = 'other thing'
var obj = {
prop1 : 'my prop',
prop2 : foo, //getting the value of external variable
prop3 : baz //getting the value of external variable
}
console.log(obj)
// change the value of prop2
obj.prop2 = 'changed'
console.log(obj)
Upvotes: 1
Reputation: 244
Here's what's happening:
"changed"
is assigned to the variable foo
foo
is assigned to obj.prop2
obj.prop2
simply gets the value. It does not get a reference to foo because these types of values (string, integer, boolean) can be stored in obj
as is.Now let's try the same thing with a different type:
var bloop = [1, 2, 3];
obj.prop4 = bloop;
console.log(obj.prop4); // [1, 2, 3]
bloop.push(4);
console.log(bloop); // [1, 2, 3, 4]
console.log(obj.prop4); // [1, 2, 3, 4]
In this case, what we assign to obj.prop4
is not a value like a string, integer, or boolean. Instead we are assigning a reference to an array stored in a different place in memory. bloop
and obj.prop4
both hold a reference to the same array in memory, so if the array is updated, both will update.
This actually works both ways:
obj.prop4.push(5);
console.log(obj.prop4); // [1, 2, 3, 4, 5]
console.log(bloop); // [1, 2, 3, 4, 5]
So in summary if you are dealing with values like strings, ints, booleans you will not be able to change an object's properties the way you are describing. It will work only when the object property is a reference to an array, object, etc.
Upvotes: 2
Reputation: 1074008
When you do
var obj = {
prop1 : 'my prop',
prop2 : foo, //referencing external variable
prop3 : baz //referencing external variable
}
there is no ongoing link between prop2
and the variable foo
(or prop3
and baz
). All that happens is that the current value of foo
is read, and stored in prop2
(and the same for baz
and prop3
).
If you need prop2
and prop3
to remain linked to foo
and baz
, you could make them properties with getters. These are properties that trigger a function call when they're read (there are also setters which trigger a function call when the property is set):
var obj = {
prop1 : 'my prop',
get prop2() { return foo; },
get prop3() { return baz; }
};
Accessing obj.prop2
is a hidden function call. Since the function closes over foo
, it returns foo
's current value.
Live Example:
var foo = 'something';
var baz = 'other thing';
var obj = {
prop1 : 'my prop',
get prop2() { return foo; },
get prop3() { return baz; }
};
console.log(obj);
foo = 'changed';
console.log(obj);
Upvotes: 16