1

I noticed that if I try to compile lines of Coffeescript like this:

$note.find('a.close').bind 'click', (event) =>
  $(this).parent().remove()

The $(this) compiles to $(_this), which makes sense considering I'm using =>. The thing is, I don't want to have to use -> in case I need to use local variables in this scope later.

Must I escape the second line with backticks to make $this compile correctly, à la:

`$(this).parent().remove()`

…or is there a better way?

Update (12 Jul 2012):

I ended up doing this:

close = -> $note.remove()
$note.find('a.close').bind 'click', (event) ->
  close()
setTimeout close, duration

I know it avoids the use of this altogether, but that seems like a cleaner solution than using the same self = this trick that developing in plain JS often requires.

Will
  • 5,654
  • 2
  • 23
  • 26
  • @arnaud576875, it's a related problem, but the answers on the question you linked would not answer this question. – Will Jul 10 '12 at 15:24
  • What is the problem that a simple `$this = $(@)` and `->` won't solve? – mu is too short Jul 10 '12 at 15:59
  • @muistooshort "The thing is, I don't want to have to use `->` in case I need to use local variables in this scope later." – Will Jul 10 '12 at 16:05
  • How does `->` prevent you from using local variables in the closure? – mu is too short Jul 10 '12 at 16:31
  • 1
    "don't want to have to use -> in case I need to use local variables in this scope later" It's not clear to me what you mean by this. You have two scopes here: the inner, which is the function scope of "=>" and the outer, which is the scope where "=>" is declared. Irregardless of whether you use => or ->, variables declared in the inner scope will not be visible in the outer scope. You can however declare variables in the outer scope, and reference them in the inner scope. Either way, I don't understand how you expect to attach an event listener without using a function via -> or => – jbeard4 Jul 10 '12 at 16:31
  • 2
    `->` vs `=>` has nothing to do with "local variables", it just meddles with the value of `@`: http://jsfiddle.net/ambiguous/yqZCy/ – mu is too short Jul 10 '12 at 16:34

3 Answers3

2

To get the element you clicked on, you can do:

close_button = $(event.currentTarget) // equivalent to $(this) here
close_button.parent().remove()

----- or -----

that = @
$note.find('a.close').bind 'click', (event) ->
    $(this).parent().remove()
    that.anotherFunc()

But it's not really answering your question, but it's a good alternative. I would use the first solution myself when possible.

Robin
  • 21,667
  • 10
  • 62
  • 85
  • 1
    `event.target` and `this` may not always be the same. – gen_Eric Jul 10 '12 at 15:13
  • In this case, it will though, right? – Robin Jul 10 '12 at 15:13
  • As long as `a.close` doesn't have any children, then yes. – gen_Eric Jul 10 '12 at 15:14
  • 2
    It can be different in case of event bubbling, but that won't be the case here. – Robin Jul 10 '12 at 15:14
  • Right, `this` and `event.target` happen to be the same in this case, but not in event bubbling scenarios. It's not a very satisfying solution, though it would work. – Will Jul 10 '12 at 15:19
  • As long as you know how it works, I think it's fine. – Robin Jul 10 '12 at 15:20
  • 1
    Or... you could use `->` and save `@` as a local variable... Not sure it's better. – Robin Jul 10 '12 at 15:21
  • 1
    [`event.currentTarget`](http://api.jquery.com/event.currentTarget/) is the proper property, not `.target` – Esailija Jul 11 '12 at 14:47
  • *sigh* I was hoping there'd be a better option than 1) avoiding using `this` or 2) doing the ol' `self = this` trick from plain JS. Thanks for your answers anyway – they really helped! – Will Jul 12 '12 at 14:49
1

You really want to use ->. The only thing that'll change is the value of this (or @) inside that function. If you want to be able to use both the this you currently have and the this you want, you'll want to keep the current this in closure under a different name

The code now:

$note.find('a.close').bind 'click', (event) ->
  $(this).parent().remove()

The code if you need the this from the outer scope:

that = this
$note.find('a.close').bind 'click', (event) ->
  that.doSomething()
  $(this).parent().remove()
Aaron Dufour
  • 17,288
  • 1
  • 47
  • 69
0

As far as i understand you need just cache you variable

that = @

context.action (e) ->
  foo(that)
CodeGroover
  • 2,157
  • 19
  • 25