Javascript memory leaks: why assign an object to zero work?

Can someone scratch the itch for me regarding the nature of the zero-based fix used to prevent memory leaks?

We are all familiar with the following method to stop the circular reference between the DOM object and the JS object in order to prevent memory leak:

function foo() { var ele = document.getElementById("someParagraphId"); ele.onclick = function() { //some action here }; ele = null; } 

The question is, why does this work? Setting "ele" to null will certainly stop circular links, but won't this also interfere with future links to "ele"?

  function foo() { var ele = document.getElementById("someParagraphId"); ele.onclick = function() { console.log("accessing ele ... after set to null " + ele.onclick); }; ele = null; } 

Still, the event is being tapped. He will complain that the "ele" object is null (this is what we expect).

Given the above behavior, can we conclude that the implementation of the Javascript mechanism will contain some internal link to the event listener, and that this link is called when the event fires?

 eventHandlerRef = //assignment to "ele.onclick" handler/listener; 

If there was a link like the one above, would it not be dependent on the implementation of assignment-to-null? Or is it part of the ECMAScript specification.

As far as I understand, this fix has always been safe for the browser. I have not come across many examples that contain specific references to detecting / sniffing a browser type before applying a null destination.

================ EDIT ==================

I think that, due to the way I posed this question, perhaps involuntarily, a direct discussion of what I tried to convey. A couple of concepts that are referenced:

object references / object references ala:

  var obj1, obj2; obj1 = {foo: "bar"}; //obj1 points to the an area of the heap allocated //for the object literal. obj2 = obj1; //obj2 points to the same position in the heap //as obj1. //obj1 = null or obj1 = {/*another obj literal*/} //the new object literal is created //and allocated in some other part //in the heap, and obj1 now points //to the new location. //obj2 is unaffected by obj1 re-assignment. 

This is not the place where my itch lies, and I regret to add the line:

 console.log("accessing ele ... after set to null " + ele.onclick); 

The above makes this question closed. I fully expected the error to be thrown as indicated in the original post.

My itch is more about context ... for some reason, in my opinion, I keep thinking that the Javascript mechanism will call ele.onlick() directly when the event fires and sets the element to zero, akin to the following thread:

 var obj = {}; obj.method = function() {}; obj = null; //error calling obj.method(), ie, obj is null 

Considering that in the original message we know that the event handler still fires after the element is set to null, in my opinion the stream is more akin to it:

 var obj = {}; obj.method = function() {}; var objRef = obj; obj = null; //The Javascript Engine calling objRef.method when event triggered. 

My question is how most Javascript works when some kind of internal link points to an assigned event handler, and that internal link is called when the event fires?

Or, in other words, what stops the implementation of the Javascript Engine from calling ele.onclick() rejecting design and architecture problems at the moment)?

Perhaps my thought processes work differently, but no one repeated the second glance when they first encountered the -null-null assignment, where the element reference was null and still the code for the handler was still executing?

+6
source share
3 answers

Removing the old answer and calling for editing :)

Consider a simpler example: textContent .

 var ele = document.getElementById('foo'); ele.textContent = 'abc'; ele = null; 

This code sets textContent from #foo to abc and drops the link to ele . Now, what happens if I ask #foo again? ...

 var ele = document.getElementById('foo'); ele.textContent = 'abc'; ele = null; ele = document.getElementById('foo'); console.log('#foo is ' + ele.textContent); 

He will record "#foo is abc" . This simply indicates that #foo lives outside of my script, and that document saves a link to it (since I got it back by calling the method on document ). It works with event handlers.

 var ele = document.getElementById('foo'); ele.onclick = function() { console.log('abc'); }; ele = null; ele = document.getElementById('foo'); console.log('#foo.onclick is ' + ele.onclick); 

Event handlers are not a special property. These are just the variables on which you write references (to functions). These are roughly the functional functions of a language, where functions can be used as simple values. The JavaScript implementation simply calls the event handlers from the DOM link, not from the ele directory. Let's make another simpler example, without document.getElementById .

 var a = {}; var b = a; b.foo = function() { console.log("hello world!"); }; console.log(a.foo + " is the same as " + b.foo); b = null; console.log("Even though b is " + b + ", a.foo is still " + a.foo); a.foo(); 

As you can see, the functions are not tied to the links to which we assign them: they are tied to the objects to which the links point. You can call them from any object reference, and not just from the one you used to assign the function.

Thus, you can nullify links to breaks of circular dependencies without affecting the correct behavior of objects.

+6
source

Since you get ele first, by calling document.getElementById("someParagraphId") , the object it references already exists in memory before you assign ele . This is part of the document - of course, there is a link to it in memory, except for ele .

0
source

I am far from a JavaScript guru; but I think I can at least partially answer your question by simply recalling the difference between a variable and an object. Let through your code one line at a time.

 var ele = document.getElementById("someParagraphId"); 

Here we do two things:

  • Variable declaration ( ele )
  • Assigning a reference to a DOM element (object) to this variable

Further:

 ele.onclick = function() { console.log("accessing ele ... after set to null " + ele.onclick); }; 

Here we use the ele variable to assign a callback to the onclick event of the object (again, the DOM element) that it refers to.

Finally:

 ele = null; 

Finally, we assign a null reference to our ele variable. It no longer refers to an object that it did just a few minutes ago. However, this object still exists, with the same onclick handler; he has not changed.

The fact that the handler is still invoked is the correct behavior. Now, regarding the error, let me take another look at the function assigned to this DOM element onclick event:

 console.log("accessing ele ... after set to null " + ele.onclick); 

This ele is the same variable that we just assigned to null . And thus, when this function is called - because, again, the onclick handler attached to the object has not disappeared - a null reference exception is thrown.

0
source

Source: https://habr.com/ru/post/890383/


All Articles