The issue is that event handlers set their own value for this
when they call the callback. That value will typically be related to the event handler, not to the object that the method is bound to. For example, in your example:
document.getElementById('foo').onClick(myObj.myFunc);
The this
pointer in myFunc
will be set to the DOM element that had the event handler attached (in this case, the foo
element). But that isn't myObj
so myFunc
in that case could not access any of it's own instance variables via the this
pointer (the normal way that methods access their instance data).
So, if you have a method that wants to access it's own instance data when it is called directly by an event handler, you have to do something other than just pass the method to the event handler. There are a couple ways to work around this issue.
One way of doing so it so use .bind()
which returns a new stub function who's function is to set this
before calling your function like this:
document.getElementById('foo').addEventListener('click', myObj.myFunc.bind(myObj));
In this case .bind()
actually returns a new stub function who's function is to set the value of this
to myObj
before it calls myFunc
.
You could also do that manually yourself like this:
document.getElementById('foo').addEventListener('click', function(e) {
myObj.myFunc();
});
But, as you can see, .bind()
provides a shortcut that takes less code (which is why it was invented).
A potential disadvantage to using .bind()
in some cases is that you may no longer have access to the value of this
that the caller of your callback would have set itself because .bind()
threw that value away and replaced it with your own. In the event handler example above, this is not an issue because the original source of the event can be accesses via the e
argument that is passed to the event handler so it is not lost if you need it.
I am aware of no meaningful difference in memory consumption or garbage collection between the two methods above. Both create a new function that is used to call the original and control the value of this
when calling the original function. Both will have the same garbage collection lifetime.
It appears that one thing that is confusing you is that objects in Javascript are assigned or passed by pointer (some call it by reference, but that has some connotations that don't apply here so I'll use the phrase by pointer).
var x = {};
x.myFunc = function() {console.log("hello");};
x.myFunc(); // generates "hello" in the console
var t = x.myFunc; // save reference to the function that x.myFunc currently points to
delete x.myFunc; // remove property myfunc from the x object
t(); // generates "hello" in the console
t()
still works event after x.myFunc has been removed because both t and x.myFunc had a reference (or pointer) to the same function. Doing a delete x.myFunc
simply removed the myFunc property from the x
object. The function that x.myFunc
points to will only be "freed" by the GC when there are no other references to it. But, there is another reference to that function in t
, so it is not freed and t()
can use it for as long as t
exists.