CoffeeScript:如何同时使用胖箭头和 this?
Posted
技术标签:
【中文标题】CoffeeScript:如何同时使用胖箭头和 this?【英文标题】:CoffeeScript: How to use both fat arrow and this? 【发布时间】:2012-09-20 19:42:42 【问题描述】:我有一个咖啡脚本类,它有一些 jquery 事件监听器。我想使用粗箭头=>
来避免引用该类,但我仍然需要引用通常与this
一起使用的元素。如何同时使用两者?
class PostForm
constructor: ->
$('ul.tabs li').on 'click', =>
tab = $(this)
@highlight_tab(tab)
@set_post_type(tab.attr('data-id'))
highlight_tab: (tab)->
tab.addClass 'active'
set_post_type: (id) ->
$('#post_type_id').val(id)
【问题讨论】:
你能多描述一下你想做什么吗?你想在哪里使用(这个),上面的哪一部分没有按照你想要的方式工作? IOW,您希望this
引用什么对象?事件的目标,PostForm 类实例等?
【参考方案1】:
CoffeeScript 将this
和@
链接到外部上下文,因此您无法访问 jQuery 提供的上下文(也就是所需的“this”)。请改用event.target
:
class PostForm
constructor: ->
$('ul.tabs li').on 'click', (event) =>
tab = $(event.target)
@highlight_tab(tab)
【讨论】:
event.target
也将我们保存在 Backbone.js
中
event.target
对于不了解 this
周围的 DOM 规则的人来说也不那么令人困惑。
请注意,如果您使用选择器执行事件,您可能需要 evt.currentTarget。见codepen.io/ddopson/pen/erLiv
你在 d3 上做什么? d3 中的回调给你对象(不是 DOM)
我不知道你写的时候是不是真的,但是 event.target 有时会返回一个与 'this' 不同的元素。点击事件回调中的“this”返回触发回调的元素,而 event.target 返回触发点击事件时鼠标所在的元素(通常是某种子元素)【参考方案2】:
使用 evt.currentTarget
您可能应该使用evt.currentTarget
(相当于this
)而不是evt.target
(不是)。如果您为click
通知而点击的节点具有子节点,则evt.target
可能是这些子节点之一,而不是您添加click
处理程序的节点。
有关此行为的演示,请参阅 http://codepen.io/ddopson/pen/erLiv。 (点击内部红色框可以看到currentTarget
指向红色div,而target
指向外部蓝色div,事件处理程序注册在上面)
$('ul.tabs li').on 'click', (event) =>
tab = $(event.currentTarget)
@highlight_tab(tab)
回答所提问题 - 获取 `=>` 和 `this`:
您可以执行以下操作...
$('ul.tabs li').on 'click', (event) =>
tab = $(` this `) # MAKE SURE TO ADD THE SPACES AROUND `this`
@highlight_tab(tab)
这些空格很关键,因为它们可以防止 Coffee 将 this
咀嚼成 _this
。
使用`self`和`->`
或者,执行以下操作...
self = this
$('ul.tabs li').on 'click', (event) ->
tab = $(this)
self.highlight_tab(tab)
这类似于 CQQL 的答案,只是我更喜欢习惯使用 self
作为变量名;我的 VIM syntax highlighting rules color self
作为一个“特殊”变量,就像 this
、arguments
或 prototype
一样。
【讨论】:
self = 这正是我所做的。效果很好! event.currentTarget 实际上与“this”不同,至少对于点击事件的 jquery 而言。它有时可能具有相同的值,但也可能不同,具体取决于具体情况。 'this' 指的是被点击的元素,而 event.currentTarget 返回正在监视点击事件的元素。 @GlyphGryph - 感谢您的澄清!【参考方案3】:我更喜欢这个版本,因为我更容易理解。
class PostForm
constructor: ->
post_form = this
$('ul.tabs li').on 'click', (event) ->
tab = $(this)
post_form.highlight_tab(tab)
【讨论】:
你将如何从课堂上的另一个函数访问 post_form? 类方法应该可以正常使用this
来引用PostForm
的当前实例。
谢谢@CQQL :) 我详细说明了我的问题,并给出了我最终得出的答案。最初我想将回调函数直接交给 click
处理程序,但后来意识到我应该首先将其包装在一个匿名函数中,该函数获取 this
并通过 self
将其传递给命名函数,以便获得最好的两个世界。【参考方案4】:
您可能希望从您的函数访问构造函数中设置的变量。这就是你的做法(关键是通过self
调用函数,同时先用细箭头提取this
):
class PostForm
constructor: ->
self = this
@some_contrived_variable = true
$('ul.tabs li').on 'click', ->
tab = $(this)
self.highlight_tab(tab)
self.set_post_type(tab.attr('data-id'))
highlight_tab: (tab) ->
# Because of the fat arrow here you can now access @ again
if @some_contrived_variable
tab.addClass 'active'
set_post_type: (id) ->
$('#post_type_id').val(id)
顺便说一句:This is a great explanation of when to use the fat and thin arrow.
总结:
-
你在函数中使用这个 (@) 吗?
您想稍后执行该函数,可能从不同的范围执行吗?
【讨论】:
您可以在highlight_tab
中访问@
,因为highlight_tab
在self
上被调用,而不是因为粗箭头。胖箭头没有任何区别。您可以通过编译这两个版本自己尝试。以上是关于CoffeeScript:如何同时使用胖箭头和 this?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 CoffeeScript 胖箭头回调中引用实际的“this”?
如何将胖箭头AngularJS转换为coffeescript