Javascript, preserving this reference when passing

2019-02-23 20:57发布

I'm inside a function of an object and I need to call an external function and pass a reference to a function as argument. This last function argument uses the keyword this several times so I need to be scoped into my object. I solved this by doing:

   MyObj.prototype.internalFunc= function(data){
       this.doSomethingWithReturnedData(data);
   };

   MyObj.prototype.doSomething= function(){
       var $this = this;
       externalFunction(this.someVar, function(data){ $this.internalFunc(data); });
   };

   var objInst = new MyObj();
   objInst.doSomething();

I want to know if there is away to avoid this messy var $this = this thing.

I also thoung of:

   //... (same as before)
   MyObj.prototype.doSomething= function(){
       var $this = this;
       externalFunction(this.someVar, this.internalFunc, this);
   };
   //... (same as before)

with

   function externalFunction(arg1, cbfunc, thisref){
       //bla bla things
       cbfunc.call(thisref, blablaData);
   };

but I also find it messy.

I think there is a better way of doing it and I'm not seeing it! Thanks in advance!

2条回答
够拽才男人
2楼-- · 2019-02-23 20:59

There is one other option available to you, if you're on a recent enough browser and that is to use Function.bind.

This allows you to create a function that has been bound to a specific scope. Put another way, it allows you to define what this will be, inside that function. Thus, you could do it this way.

MyObj.prototype.doSomething= function(){
   externalFunction(this.someVar, this.internalFunc.bind(this, data));
};

Follow the link above and scroll to the bottom to see information about browser support.

Edit

Actually, there's one other option, which is to use one of the many libraries and frameworks that are out there. Any one worth its salt will have a bind, hitch, proxy or otherwise available to you. However, all these are doing are wrapping up the native JS approaches, but they often provide useful additions that make this technique even more valuable.

查看更多
小情绪 Triste *
3楼-- · 2019-02-23 21:10

Assigning this to a local variable is fine and common.

Many libraries make your second approach easier by providing a method that returns a wrapper function and sets the execution context, e.g. $.proxy in jQuery (or _.bind in underscore.js).

查看更多
登录 后发表回答