Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Object copied to second property via reference persists even after original property deleted?

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! :)

like image 664
Noitidart Avatar asked Oct 27 '14 08:10

Noitidart


4 Answers

...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):

  1. Initialization of the empty object a with another object (value:true).

enter image description here

  1. Assigning the empty object a with a property b referring to the other object (value:true).

enter image description here

  1. Assigning the object a with a property c referring to the same object (value:true).

enter image description here

  1. Deletion of the key b, thus a.b no longer refers to the sub-object (value:true).

enter image description here

  1. Final representation of the main object a.

enter image description here

So we can easily see by visual representation how the sub-object was being preserved :)

like image 83
user3459110 Avatar answered Nov 10 '22 17:11

user3459110


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.

like image 23
Frost Avatar answered Nov 10 '22 17:11

Frost


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.

like image 6
axelduch Avatar answered Nov 10 '22 17:11

axelduch


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.

like image 5
Sharadh Avatar answered Nov 10 '22 19:11

Sharadh