I'm fairly experienced programming but quite new to TypeScript.

Trying to use it with jQuery and immediately ran into the 'this' issue with callbacks (such as $(document).ready.

Using $.proxy() is one way to go, but using TypeScript's arrow (lambda) functions seemed much better. But I only see them used as expressions — that is the entire function is defined inline. I would like to be able to set up arrow functions that could be called as methods of my class, something like (in pseudocode):

class Something {
    constructor() {
    $(' nav li').click(this.menuClick);
    }
 private menuClick (and this would be an arrow function to preserve 'this')()=>    
  // it would call this.anotherMethod()
  // plus lots of other things so it won't easily fit inline

 private anotherMethod():void {
        // do something on the menu click, several lines perhaps, 
  }

}

I come from an OOP background in AS3, and that's how I was able to do it -- 'this' was readily accessible or it was clear how to access it. I'm keen to use TypeScript to get past the OOP hurdle I'm having with Javascript plain -- but it seems cumbersome (to me) to have to proxy all the jQuery calls (I know there are classes out there to do this for me, but is there a simpler way, with arrow/lambda functions?).

Have patience if I'm not grokking the obvious, but it ain't obvious to me!

share|improve this question
feedback

2 Answers

The reason there isn't a way to do this by default is that it's a tremendous runtime cost in terms of per-instance memory consumption if done automatically. Rather than having one base prototype object with all the functions in it and each class instance pointing to that prototype for its function definitions, you end up having a closure per function for every instance of the class.

There might be better type system support for this in the future, but for now, dealing with this binding issues is just a tax you have to pay when writing JavaScript of any flavor. Hopefully as things like TypeScript gain momentum, library authors will reduce their usage of this-stomping (though the DOM will never have that luxury).

The upside is that in TypeScript, it's not a huge amount more code when you do need to re-re-bind this:

$(' nav li').click(() => this.menuClick());

or

$(' nav li').click(this.menuClick.bind(this));

share|improve this answer
+1 great detail along with the code. – Steve Fenton Dec 13 '12 at 11:41
Thanks. When I compile the code $(' nav li').click(() => this.menuClick()); I get Supplied parameters do not match any signature of call target for that line of code because I'm defining menuClick with a parameter so I can access the element clicked, thus: private menuClick(event:JQueryEventObject):void { var li:JQuery = $(event.target).closest('li'); } --- how would I do the arrow call correctly then? – Robert Dec 13 '12 at 16:25
This should work : $(' nav li').click((eventData) => this.menuClick(eventData)); – BreeeZe Dec 13 '12 at 18:01
feedback

The short answer:

If you change : $(' nav li').click(this.menuClick);

into : $(' nav li').click(()=> this.menuClick ());

then "this" will be your class 'Something' inside the 'menuClick' method.

share|improve this answer
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.