1

Lets say I have defined an object.

let obj = {
   "key": "prop"
}

And make use of this object reference in an array

const arr = [ obj ]

And now I make the object (obj) reference to null.

obj = null

So basically I have removed the reference of object (obj) which I have declared. So now if access Array (arr) items, I should get null as item. Not the object (obj) which I have defined earlier.

console.log(arr) // [ { "key": "prop" } ]
console.log(obj) // null

I am not able to get it exactly why is this happening. I have been asked this question in an interview.

I also found out that if we use Set instead of Array, then obj will be defined as null in WeakSet. So that means, it is garbage collected in this case at least.

user10169731
  • 131
  • 11
  • I would say, JS is internally creating a copy when setting to null. – Markus Zeller Feb 11 '21 at 20:53
  • 1
    @MarkusZeller: No, JS is "creating a copy" when setting the reference in the array. And what it's "creating a copy" of is the reference to the object in memory. – David Feb 11 '21 at 21:00
  • 1
    The last paragraph is not true. It works the same way with a Set. If you don't agree, then add a runnable snippet to your question that proves your point. – trincot Feb 11 '21 at 21:00
  • @trincot I wanted to write WeakSet, it is just a typo. – user10169731 Feb 11 '21 at 21:01
  • 1
    OK, but then you cannot access the object anymore. With array you can write `console.log(arr[0])`, and still access the object (which is why it is not garbage), while with the WeakSet you have no way to access the object... there is no syntax for it. Garbage collection only happens when there is absolutely no way for your code to access that memory. – trincot Feb 11 '21 at 21:06
  • Thanks, @David. That makes sense. I came up to the idea, because PHP behaves completely different. When you call a PHP function with an array, it is handled as reference as long as you read it. On a write access, it creates a copy when not explicitly passed by reference. – Markus Zeller Feb 11 '21 at 21:16
  • @trincot thank for explaining. Now I understood why is this happening. – user10169731 Feb 12 '21 at 22:12

1 Answers1

3

obj is just a variable, not a reference. Such references don't exist in JavaScript. When you assign null to it, you are just changing that value that is stored in obj, but the object is still in memory because you made it accessible through arr[0]

That is, obj is just a container for some object that is stored in memory. It's true that obj holds a reference to it, not a copy, so that when you assign obj to some other variable, that variable will hold the same object, but reassigning obj does not affect the object in the memory.

Edit: Since op editted the question effectively making it different from the tagged question that this was a duplicate of, I will answer that question too, shall I?

From the MDN Page on WeakSet

The WeakSet is weak, meaning references to objects in a WeakSet are held weakly. If no other references to an object stored in the WeakSet exist, those objects can be garbage collected.

When you assign null to obj, you remove that objects' only reference other than the one held internally by the WeakSet, so it can be garbage collected since that object is now effectively unaccessible, the WeakSet is not enumerable.

Stefan Octavian
  • 593
  • 6
  • 17
  • 2
    That is confusing. I would say `obj` *is* a reference (at first). But the point is that a reference is not the actual content that is being referenced. And assigning a different reference (or `null` or anything else) will destroy that reference, but not what was referenced. – trincot Feb 11 '21 at 20:57
  • Okay. But then why it is getting set to null if we user WeakSet? Is it because of the way WeakSet has been implemented? – user10169731 Feb 11 '21 at 20:58
  • 2
    @user10169731, If you have a question that involves WeakSet, then you should ask it that way (preferrably with a runnable snippet). – trincot Feb 11 '21 at 20:59
  • @trincot, yes, that's more or less how I understand it too, I haven't read the ecma spec yet (but I want too). I added to my answer (before seeing your comment) and I think it reflects what you're saying. – Stefan Octavian Feb 11 '21 at 21:05