frankfullstack
frankfullstack

Reputation: 550

JavaScript Sets lost reference but don't change size

I'm storing objects references inside my JavaScript Sets:

let set1 = new Set();
let obj  = {};

Then if I use the has() method and the size property of the Set objects I get the next results:

console.log(set1.size) //it returns 1
console.log(set1.has(obj)) //it returns true

But, if I remove the reference of the object using the next code:

obj = null;

Then strange behaviour happens to me:

console.log(set1.size); //it returns 1 because they are Hard Sets.
console.log(set1.has(obj)); //it returns false

In the last line, why does it return false if the size is not changed? Then the reference is lost but the size is not changed.

Upvotes: 3

Views: 236

Answers (2)

nils
nils

Reputation: 27204

When you override the value of obj:

obj = null;

You are only changing the value of obj, not of the Set entry, which still holds a reference to the object that was originally assigned to obj.

So the current state is:

obj: null
set1: [
   {} // the object assigned to obj
]

So your line

console.log(set1.has(obj));

actually tests, if set1 contains null:

console.log(set1.has(null));

which is of course false (as it only contains the object).

To actually delete the object from the set, you can use:

set1.delete(obj);

You could also use a weakSet, if the reference in the set in only used as long as the reference to that object still exists somewhere else.

Upvotes: 1

zerkms
zerkms

Reputation: 255005

In the last line, why does it return false if the size is not changed?

It returns size = 1 because it still holds one value (a reference to that object).

It returns false because it does not has a value that is equals to null.

But, if I remove the reference of the object using the next code:

You just overwrite a value of the variable. After that there is still one reference to the object left (inside the Set).

To remove an element from a Set you need to use Set.prototype.delete() method:

set1.delete(obj);

Presumably you need to do that while obj still holds a reference to the object.

Upvotes: 1

Related Questions