I thought objects are passed as reference. But when I delete b
, it still exists in c
. Please see this example:
This first part makes sense to me as its passed by reference:
var a = {b: {val:true}};
a.c = a.b;
a.b.val = 'rawr';
console.log(uneval(a)); // outputs: "({b:{val:"rawr"}, c:{val:"rawr"}})"
Now this part does not make sense to me:
var a = {b: {val:true}};
a.c = a.b;
a.b.val = 'rawr';
delete a.b;
console.log(uneval(a)); // outputs: "({c:{val:"rawr"}})"
so b
property is deleted, but c
property is holding the properties to what the referenced before delete. is this a bug in javascript?
edit: thanks all to the replies! so its not a bug, and this behavior is actually very good, it allows people to change "key"/"property" names while retaining the object! :)
...I am late to the party? Here is my take on explaining it (Read the other answers as well, this is just to support those answers with a visual representation):
a
with another object (value:true
).a
with a property b
referring to the other object (value:true
).a
with a property c
referring to the same object (value:true
).b
, thus a.b
no longer refers to the sub-object (value:true
).a
.So we can easily see by visual representation how the sub-object was being preserved :)
No, this is not a bug in JavaScript.
What you are doing with a.c = a.b
is that you are creating another link to the same object, meaning that both a.b
and a.c
are referencing the same sub-object {val: "rawr"}
.
When you do delete a.b
, you are not removing the sub-object, you are only removing the a.b
property from a
. This means that a.c
will still reference the same object.
If you were to delete the a.c
property as well, then the sub-object will vanish.
There are two things to note, first, as said in other answers, the delete keyword removes a property only for the object through which you go to access the property.
The second thing to note is that JavaScript does not pass by reference, ever. It always passes as a value, values are sometimes references.
For instance:
var a = {
someObject: {}
};
var someObject = a.someObject;
someObject = 'Test';
console.log(a.someObject); // outputs {}
In a language which passes by reference this would probably cause an error because it often implies strong variable typing.
That's because:
The delete operator removes a property from an object. MDN Delete
The entry b
that corresponds to the Object {val: true}
is removed from a
. The entry c
in a
still refers to this object. If you try deleting c.val
or a.b.val
, you can still see the effect cascading to the other.
What you're trying to do, i.e, deallocating data and expecting it to be cascaded across, doesn't happen in javascript. If you have a C++ background, consider thinking of all javascript objects as being reference counted. Ican remove a reference to it (i.e, the entry that 'points' to this object), but I can't remove the object itself. That is the pure prerogative of the javascript engine.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With