CoffeeScript,何时使用粗箭头 (=>) 超过箭头 (->),反之亦然
在 CoffeeScript 中构建类时,是否应使用 =>
(“粗箭头”)运算符定义所有实例方法,并使用 ->
-> 定义所有静态方法代码> 运算符?
When building a class in CoffeeScript, should all the instance method be defined using the =>
("fat arrow") operator and all the static methods being defined using the ->
operator?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
不,这不是我会使用的规则。
我在定义方法时发现的粗箭头的主要用例是当您想要使用方法作为回调并且该方法引用实例字段时:
如您所见,您可能会遇到将引用传递给实例的问题如果您不使用粗箭头,则将方法作为回调。这是因为粗箭头将对象的实例绑定到
this
而细箭头则不然,因此如上所述作为回调调用的细箭头方法无法访问实例的字段,例如 < code>@msg 或调用其他实例方法。最后一行有一个针对使用细箭头的情况的解决方法。No, that's not the rule I would use.
The major use-case I've found for the fat-arrow in defining methods is when you want to use a method as a callback and that method references instance fields:
As you see, you may run into problems passing a reference to an instance's method as a callback if you don't use the fat-arrow. This is because the fat-arrow binds the instance of the object to
this
whereas the thin-arrow doesn't, so thin-arrow methods called as callbacks as above can't access the instance's fields like@msg
or call other instance methods. The last line there is a workaround for cases where the thin-arrow has been used.其他答案中未提及的一点需要注意的是,在不必要时将函数与粗箭头绑定可能会导致意想不到的结果,例如在本示例中,我们将调用一个名为 DummyClass 的类。
在这种情况下,这些函数完全符合人们的预期,并且使用粗箭头似乎没有任何损失,但是当我们在定义 DummyClass 原型后修改它时会发生什么(例如更改一些警报或更改日志的输出) :
正如我们所看到的,覆盖我们之前定义的原型函数会导致 some_function 被正确覆盖,但 other_function 在实例上保持不变,因为粗箭头导致类中的 other_function 绑定到所有实例,因此实例不会引用回它们的类来查找函数
即使是粗箭头也不起作用,因为粗箭头只会导致函数绑定到新实例(这确实会像人们所期望的那样获得新函数)。
然而,这会导致一些问题,如果我们需要一个可以在所有现有实例(包括事件处理程序)上工作的函数(例如,在将日志记录功能切换到输出框或其他东西的情况下)怎么办[因此我们不能使用原始定义中的粗箭头],但我们仍然需要访问事件处理程序中的内部属性[我们使用粗箭头而不是细箭头的确切原因]。
实现这一点的最简单方法是在原始类定义中仅包含两个函数,一个用细箭头定义,它执行您希望执行的操作,另一个用粗箭头定义,除了调用第一个函数之外什么都不做例如:
因此,何时使用细箭头/粗箭头可以通过四种方式相当简单地总结:
当满足两个条件时,应使用单独的细箭头函数:
该
当满足以下条件时,应使用单独的胖箭头函数:
当满足以下条件时,应使用直接调用细箭头函数的粗箭头函数:
当满足以下条件时,应使用直接调用粗箭头(未演示)函数的细箭头函数:
在所有方法中,必须考虑原型函数可能更改的情况,无论特定实例的行为是否例如,尽管函数是用粗箭头定义的,但其行为会正确运行如果实例调用原型内更改的方法,则实例内可能不一致
A point not mentioned in other answers that is important to note is that binding functions with fat arrow when it is not necessary can lead to unintended results such as in this example with a class we'll just call DummyClass.
In this case the functions do exactly what one might expect and there seems to be no loss to using fat arrow, but what happens when we modify the DummyClass prototype after it's already been defined (e.g. changing some alert or changing the output of a log):
As we can see overriding our previously defined function of the prototype causes some_function to be correctly overwritten but other_function remains the same on instances as fat arrow has caused other_function from the class to be bound to all instances so instances won't refer back to their class to find a function
Even fat arrow won't work as fat arrow only causes the function to be bound to new instances (which do gain the new functions as one would expect).
However this leads to some problems, what if we need a function (e.g. in the case of switching a logging function to an output box or something) that will work on all existing instances (including event handlers) [as such we can't use fat arrows in original definition] but we still need access to internal attributes in an event handler [the exact reason we used fat arrows not thin arrows].
Well the simplest way to accomplish this is to merely include two functions in the original class definition, one defined with a thin arrow which does the operations that you wish to execute, and another defined with a fat arrow that does nothing but call the first function for example:
So when to use thin/fat arrows can be summed up fairly easy in four ways:
Thin arrow alone functions should be used when the both conditions are mett:
Fat arrow alone functions should be used when the following condition is met:
Fat arrow function which directly calls a thin arrow function should be used when the following conditions are met:
Thin arrow function which directly calls a fat arrow (not demonstrated) function should be used when the following conditions are met:
In all approaches it must be considered in the case where the prototype functions might be changed whether or not behaviour for specific instances will behave correctly for example although a function is defined with a fat arrow its behaviour may not be consistent within an instance if it calls a method that is changed within the prototype
通常,
->
就可以了。请注意静态方法如何返回
this
的类对象,而实例如何返回this
的实例对象。发生的情况是调用语法提供了
this
的值。在此代码中:默认情况下,
foo
将是bar()
函数的上下文。所以它只是按照你想要的方式工作。当您以某种不使用点语法进行调用的其他方式调用这些函数时,您只需要粗箭头。在这两种情况下,使用粗箭头来声明该函数将允许它们工作。但除非你正在做一些奇怪的事情,否则通常不需要这样做。
因此,在您确实需要
=>
之前,请使用->
,并且默认情况下切勿使用=>
。Usually,
->
is fine.Note how the static method return the class object for
this
and the instance returns the instance object forthis
.What's happening is that the invocation syntax is providing the value of
this
. In this code:foo
will be the context of thebar()
function by default. So it just sorta works how you want. You only need the fat arrow when you call these function in some other way that does not use the dot syntax for invocation.In both of those cases, using a fat arrow to declare that function would allow those to work. But unless you are doing something odd, you usually don't need to.
So use
->
until you really need=>
and never use=>
by default.只是一个了解粗箭头不起作用的示例
:(@canvas undefined)
起作用:(@canvas Defined)
just an example for unstanding the fat arrow
not works: (@canvas undefined)
works: (@canvas defined)