Preserve 'this' reference in javascript prototype event handler [duplicate]

痞子三分冷 提交于 2019-11-26 20:43:22

I find bind() being the cleanest solution so far:

this.bar.onclick = this.ClickEvent.bind(this);

BTW the other this is called that by convention very often.

Check out the MDN document on bind: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

Using this functionality, you can change the scope (what this is):

Example.prototype.SetEvent = function(){
    this.bar.onclick = this.ClickEvent.bind(this);
};

Be aware, however, that this is a new addition to EMCA and thus may not be supported in all user agents. There is a pollyfill available at the MDN document linked above.

The problem with bind is that is only supported by IE9+.

The function can be polyfilled with es5-shim, but it's not completely identical to the native implementation:

  • Caveat: the bound function has a prototype property.
  • Caveat: bound functions do not try too hard to keep you from manipulating their arguments and caller properties.
  • Caveat: bound functions don't have checks in call and apply to avoid executing as a constructor.

Another alternative can be jQuery.proxy:

$(elem).on('click', $.proxy(eventHandler, this));

This is even more helpful if you want to remove the event handler later, because when a function goes through the proxy method, jQuery generates a new guid value and then applies that guid to both the core function as well as the resultant proxy function, so that you can use the original function reference to unbind an event handler callback that has been proxied:

$(elem).off('click', eventHandler);

Other solution: use the "arrow functions" introduced by ES6. Those have the particularity to not change the context, IE what this points to. Here is an example:

function Foo(){
    myeventemitter.addEventListener("mousedown", (()=>{
        return (event)=>{this.myinstancefunction(event)}; /* Return the arrow
function (with the same this) that pass the event to the Foo prototype handler */
    })());
}
Foo.prototype.myinstancefunction = function(event){
    // Handle event in the context of your Object
}

Arrow function specs @ MDN

Edit

Be carefull with it. If you use it client-side and you can't be sure of the capabilities of the JS interpreter, note that old browser won't recognize arrow functions (see CanIUse stats). Use this method only if you KNOW what will run it (recent browsers only & NodeJS apps)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!