Skip to content Skip to sidebar Skip to footer

Why 'this' In Object Function Is Different When Called Directly From AddEventListener

Why does calling an object function straight from an addEventListener make this point to calling element, but calling from a third party function makes this point to the object and

Solution 1:

When you do this:

document.addEventListener('mousedown', obj.objFunction);

You are only passing a reference to the objFunction function. There is no reference at all to obj passed. So, when the event system calls the callback objFunction is just calls it as a normal function no different than this:

 var fn = obj.objFunction;
 fn();

Thus, the context of the object is lost entirely and the method is just called as if it was a normal function. There are several work-arounds.

document.addEventListener('mousedown', function(e) {return obj.objFunction(e)});

or

document.addEventListener('mousedown', obj.objFunction.bind(obj));

Both of these work-arounds create a small stub function that is what the event handler calls and then the stub turns around and calls obj.objFuntion() with the appropriate object reference which causes this to be set to obj.


In case you aren't familiar with how this is set in javascript, it's worth some reading on that. Here's one reference and another reference. How this is set is determined by how a function is called (not by how the function is defined). In a nutshell, there are these cases:

  1. Normal function call fn() - this is set to the global object or undefined (in strict mode).

  2. Method call obj.method() - this is set to obj inside the method.

  3. Using fn.apply(x) or fn.call(x) - this is set by the first argument to .apply() or .call().

  4. Using var newFn = fn.bind(x) - When newFn() is called, this is set to the first argument passed to .bind().

  5. Using new with a constructor function as in var x = new Fn(); - In the constructor function this will be set to a newly created object of the Fn type.


Solution 2:

var bind = function bind(context, name) {
    return function () {
        return context[name].apply(context, arguments);
    };
};

var obj = {
    me: 'obj',
    objFunction: function () {
        document.body.innerHTML += this.me;
    }
};

document.addEventListener('mousedown', bind(obj, "objFunction"));
document.addEventListener('mouseup', thirdParty);

function thirdParty() {
    obj.objFunction();
}

Post a Comment for "Why 'this' In Object Function Is Different When Called Directly From AddEventListener"