Skip to content

Instantly share code, notes, and snippets.

@silasjmatson
Last active December 31, 2015 19:09
Show Gist options
  • Save silasjmatson/8031508 to your computer and use it in GitHub Desktop.
Save silasjmatson/8031508 to your computer and use it in GitHub Desktop.

Given the following CoffeeScript class:

class Foo

  constructor: ()->
    @bar()

  bar: ->
    $("body").on "click", (e)=>
      @baz(this)

  baz: (something)->
    console.assert(something == $("body"))

The following Javascript is produced:

(function() {
  var Foo;

  Foo = (function() {
    function Foo() {
      this.bar();
    }

    Foo.prototype.bar = function() {
      var _this = this;
      return $("body").on("click", function(e) {
        // Replaces both @ and this with _this
        return _this.baz(_this);
      });
    };

    Foo.prototype.baz = function(something) {
      return console.assert(something === $("body"));
    };

    return Foo;

  })();

}).call(this);

Shouldn't Coffeescript only replace @ with _this inside the callback? I'd like for this to be explicit and never treated magically, as is @.

It would certainly make behavior easier to understand.

@silasjmatson
Copy link
Author

To work around, as the CoffeeScript compiler currently is:

class Foo

  constructor: ()->
    @bar()

  bar: ->
    _this = this
    $("body").on "click", (e)->
      _this.baz(this)

  baz: (something)->
    console.assert(something == $("body"))

@jamonholmgren
Copy link

class Foo

  constructor: ()->
    @bar()

  bar: ->
    baz = @baz
    $("body").on "click", (e)->
      baz(this)

  baz: (something)->
    console.assert(something == $("body"))

@silasjmatson
Copy link
Author

Changing behavior would probably be a massive, breaking change, but I think the explicit this in code should be left alone.

@dfkaye
Copy link

dfkaye commented Dec 19, 2013

What should this to refer to?

bar: ->
  $("body").on "click", (e)=>
    @baz(this)

@silasjmatson
Copy link
Author

I'd like for it to refer to the HTML body element. So the compiled would be:

_this.baz(this);

Coffeescript has @, why treat this magically as well?

From what Jamon has said, CS compiles @ into this as one of the first steps, so it'd be a fairly complex rewrite.

@silasjmatson
Copy link
Author

I understand that die-hard js devs hate using @, so that's a major reason against forcing the explicit this, but I'd like to see if there are other reasons I'm not getting.

@dfkaye
Copy link

dfkaye commented Dec 19, 2013

Ah! Don't use this in a DOM event callback, use e.target || e.srcElement instead

@silasjmatson
Copy link
Author

@dfkaye, I'm aware of e.target and e.srcElement, but I still think that this shouldn't be treated magically, as @ is.

Using the => syntax, you lose the ability to access the actual this in the closure. There might be cases where one needs to access the closure, right?

I realize that this is trivial, and a workaround (or the proper way, depending on how you see it) is one extra line of code (or a few more characters, if it's a DOM event callback), but why does CoffeeScript bother with the => syntax when you can only use it sometimes?

@jamonholmgren
Copy link

That's a great point, @dfkaye. You're correct that e.target || e.srcElement would be more explicit and avoid this whole ambiguity altogether. In fact, using this is probably an anti-pattern to start with, despite jQuery's reliance on it.

I think the => syntax should only be used on very simple methods that do not need to refer to the child enclosure.

@silasjmatson
Copy link
Author

I think the only two places I've been using => are event callbacks and ajax callbacks.

@jamonholmgren
Copy link

Should make it relatively easy then! :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment