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
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.
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.
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.
With this line, you think c points to b:
a.c = a.b;
but actually both c and b point to {val:true} object, so if you delete b, the object remains. you can think simply that both c and b are just "label" is sticked on {val:true} object
No, it's not a bug.
The delete
command doesn't delete the object that that the property is referencing, it only deletes the property. If the object is referenced from somewhere else (the other property in this case), the object is still alive.
This is the same as if you have two variables pointing to the same object, and change the value of one variable:
var a = { val: true };
var b = a;
a = null;
console.log(b.val); // b still has a reference to 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 :)