Reputation:
Please read the comments in the code below to know what I am trying to ask.
Expected Output: As per pass-by-reference mechanism in JavaScript, objOne
is expected to log {}
at the end, because objTwo
was initialized with {}
.
var objOne = {
x: 1,
y: 2
};
var objTwo = objOne;
// change the x vlaue to 2 by objTwo
objTwo.x = 2;
// Change the value of key x in objOne as well - pass by reference mechanism
console.log(objOne); // { x: 2, y: 2 }
/*** Pass by reference is understood in code, above this comment ***/
// Now what if objTwo initialized with empty object
objTwo = {};
console.log(objOne); // { x: 2, y: 2 } but expected output = {}
// As per pass by reference mechanism. objOne is expected to log {}, because objTwo was initialized with {}.
Upvotes: 31
Views: 32845
Reputation: 350137
As per pass-by-reference mechanism in JavaScript
Let's get this out of the way: there is no pass-by-reference mechanism in JavaScript. Pass-by-reference is a very specific feature. To know whether a language supports it, you should check whether it is possible to pass a variable with an immutable value to a function (for instance an integer), and after that call see that this variable has a different immutable value. If this is not possible, then the language does not support pass-by-reference. JavaScript does not support it. C does not support it. C++ does support it (by declaring a function parameter with &
).
As to your code example; let's visualise it.
After the first two var
statements we get this:
objOne
↓
┌───────────┐
│ x: 1 │
│ y: 2 │
└───────────┘
↑
objTwo
Only one object was created (using object literal syntax).
After objTwo.x = 2
, we get:
objOne
↓
┌───────────┐
│ x: 2 │
│ y: 2 │
└───────────┘
↑
objTwo
Only one property value was changed, in the only object that was created. Whether you look at the object via variable objOne
or objTwo
does not make a difference.
objTwo = {}
creates a second object and assigns its reference to objTwo
. Now we have two, distinct objects:
objOne
↓
┌───────────┐
│ x: 2 │
│ y: 2 │
└───────────┘
objTwo
↓
┌───────────┐
└───────────┘
You cannot change which object objOne
is referencing without making an assignment to objOne
. Even though objOne
and objTwo
first referenced the same object, these variables are still distinct references. In the first phase we saw we can mutate the object that objOne
references, but it is still the same object -- just one that was subject to some mutation. It is not possible to make objOne
reference another object by making an assignment to objTwo
. You really need to assign to objOne
to make that happen.
There is no pass-by-reference mechanism in JavaScript. In JavaScript objects are accessed and manipulated through references. objTwo
is not an alias for objOne
, it only is a duplicate reference for the same object. As soon as another reference is assigned to objTwo
, we have two distinct references.
Upvotes: 1
Reputation: 1104
This is how pass-by-reference works. Here objTwo is referring to objOne so whatever you do with objTwo will also happen with objOne.
Upvotes: 0
Reputation: 65
I agree with accepted answer, this is just some code to back it up.
let objOne = {x: 1, y: 2};
let objTwo = objOne; // referencing to same thing
objTwo.x = 2;
console.log(objOne, objTwo); // output {x:2, y:2}, {x:2, y:2}
let objThree = {};
objTwo = objThree; // notice this. Same as "objTwo = {}", except now you have objThree as initial reference
console.log(objOne, objTwo, objThree); // output {x:2, y:2}, {}, {}
You can easily notice what happened by changing objTwo reference or adding it complete new value as it was shown in question example.
Upvotes: 4
Reputation: 1720
JavaScript pass by reference is different, your object is treated as a reference as long as you're changing its attributes like obj.x = 1, but assignment of the object variable itself (obj = []) will treat it as value-based variable.
Upvotes: 1
Reputation: 4584
only delete can call initialize state ..
for(var i in objOne){
delete objOne[i];
}
@nrabinowitz saying
Upvotes: 1
Reputation: 522016
When you assign one variable to another, it's not that both those variables are now linked by reference; you're misunderstanding what "pass by reference" means here.
A variable holding an object does not "directly" hold an object. What it holds is a reference to an object. When you assign that reference from one variable to another, you're making a copy of that reference. Now both variables hold a reference to an object. Modifying the object through that reference changes it for both variables holding a reference to that object.
When you assign a new value to one of the variables, you're just modifying the value that variable holds. The variable now ceases to hold a reference to the object, and instead holds something else. The other variable still holds its reference to the original object, the assignment didn't influence it at all.
Upvotes: 53
Reputation: 49095
When 2 variables are pointing to same object, it doesn't mean that they're now magically 'tied' to each other.
In your case, objTwo = {}
is simply changing objTwo
to point at the new object you created.
Upvotes: 7
Reputation: 119837
objTwo = {};
doesn't work the way you think it works. I usually recommend thinking of variables as "pointers".
objOne
and objTwo
are two totally different variables. When you did objTwo = {};
, what it did was have the objTwo
variable point to another object. It does not alter the objOne
variable.
Let's visualize:
var objOne = {
x: 1,
y: 2
};
// objOne -> { x: 1, y: 2 }
var objTwo = objOne;
// objOne -> { x: 1, y: 2 } <- objTwo
objTwo.x = 2;
// objOne -> { x: 2, y: 2 } <- objTwo (update object via objTwo variable)
objTwo = {};
// objOne -> { x: 2, y: 2 }, objTwo -> {}
Upvotes: 5
Reputation: 4092
When you evaluate
objTwo = {};
Javascript interprets that as reassigning objTwo to a new literal empty object, and leaves its old value alone.
If you want to remove a key from objOne by reference, you can use the delete
keyword:
delete objTwo.x; // also deletes the x property of objOne
Upvotes: 14