Hacker News new | past | comments | ask | show | jobs | submit login

Do you have an example of a real-world piece of code that wants to access both the lexical and dynamic "this" ... and isn't a jQuery callback?



> Do you have an example of a real-world piece of code that wants to access both the lexical and dynamic "this"

Yes.

> and isn't a jQuery callback?

No :^). And I wish JQuery ran the callback with a parameter too, so I could access 'this' to refer to the class and use the argument to refer to the object I'm going to run the callback on.

You're totally right that would be neater. Alas Coffeescript is a lot newer than JQuery, so despite technical neatness (or lack thereof in JQuery), Coffeescript has to work with JQuery to grow in popularity.

PS. Thanks for making Coffeescript. It's got me excited about JS again and I absolutely love it.


You're in luck then. This is precisely what the fat arrow in CoffeeScript is for: creating a function where the value of "this" is bound lexically. So:

    class Widget
      render: ->

        $(".widget-title").click (e) =>
          # `this` is still the Widget instance. 
          # `e.currentTarget` is the DOM element.


I was using the fat arrow, and wanted to keep using it, but switched to thin arrow (using @ to access the element and 'that' to access the class). Here's why:

click() works because the callback is given parameter:

    .click( handler(eventObject) )
Cool. You access @ for the class, and eventObject for the thing you clicked.

But I wasn't using click(), I was using load(), which has a different syntax:

    .load( url, [data,] [complete(responseText, textStatus, XMLHttpRequest)] )
I may be missing something - I only started doing JS seriously last year - but 'complete' doesn't seem to be provided with any parameters, like the element I just loaded. So my only choice, AFAICT, is to use 'this' to access that element. I'd be delighted if that was wrong though. :^)

Background: I was trying to get the width of an image file that wasn't in the document, so I could use it to size another image (which happened to use the first image as a webkit mask). Great fun.


Correcting self: that's the documentation for the wrong .load()! (yes, there's two). The proper docs are http://api.jquery.com/load-event. Which indeed allows the event to be passed to the callback explicitly, so inside the callback @ refers to the object and 'event' (or whatever) .target refers to the image. Problem solved!


What's wrong with jQuery callbacks? ;)


jQuery generally abuses (or takes advantage of, depending on your perspective) the value of "this" in its callback functions, in places where it would really be better to have an explicit argument. For example:

    AccountView.prototype.render = function() {
      $(".account").click(function(e) {
        // `this` is now the same as `e.currentTarget`
        // But `e.target` is also useful.
        // And you what you really want is for `this`
        // to still point at the AccountView instance.
      });
    };


@jashkensas what you want though would break the way closures are handled in javascript. What you should do if you still want access to Accountview is to trap a variable with a reference to it in the closure. Using your jquery example:

  AccountView.prototype.render = function() {
    $(".account").click( { that: this }, function(e) {
      // 'that' now holds a reference to AccountView
    });
  };
If you don't want to use (or you are using an older version of jquery without the eventData) you could use a closure:

  $(".account").click( (function(that) {
    return function(e) {
      // 'that' now holds a reference to AccountView
    })(this);
  });


Yes, functions in JavaScript have dynamic "this" instead of lexical "this" -- that's part of the point we're discussing. It helps when defining ad-hoc prototypes, but hurts when writing callback functions (or any nested function, really) ... and is an active point of concern for the ES committee.


No, it's a jQueryism. How would it break the way closures are handled in JavaScript?

You realize you're replying to the author of CoffeeScript?


LoL I did not realize that. To me, I think I've just made my peace with the way it is. I don't think that jQuery needs to be changed in the way mentioned though - to me, 'this' is context sensitive and in this case, it would refer to the current object and not the container




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: