Tipps zum Golfen in CoffeeScript

8

Welche Tricks kennen Sie, um den CoffeeScript-Code zu verkürzen?

CoffeeScript ist eine Sprache, die in JavaScript kompiliert wird ("transpiliert" in ES3, um genau zu sein). Die goldene Regel lautet "Es ist nur JavaScript", was bedeutet, dass kein Laufzeitaufwand entsteht. Die meisten Tipps und Tricks zu JavaScript gelten ebenfalls.

Als Nebeneffekt bedeutet dies auch: Entwickler aus JavaScript (einschließlich meiner selbst) verwenden in der Regel JavaScript-Konstrukte anstelle kürzerer CoffeeScript-Alternativen.

Dieser Thread konzentriert sich auf Tipps, die für CoffeeScript spezifisch sind.

Links zu verwandten Themen:

Tipps zum Golfen in JavaScript

Tipps zum Golfen in ECMAScript 6 und höher

metalim
quelle
Kann Coffeescript mit ES6 kompiliert werden? Ist es kompatibel?
stolzer Haskeller
@proudhaskeller Es wird im Allgemeinen in ES3 kompiliert, mit einer Ausnahme: Wenn Sie yield, wird es in ES6-Generator kompiliert. Andernfalls wird versucht, so browserkonform wie möglich zu sein.
Metalim

Antworten:

3

Verwenden Sie Destrukturierungszuweisungen, wenn häufig Strukturelemente verwendet werden

Z.B. Elemente des ersten Argumentarrays abrufen

func = ([x,y,z])->
    [i,j] = doSomething x, y, x+y
    doSomethingElse i, j

# instead of

func = (a)->
    b = doSomething a[0], a[1], a[0]+a[1]
    doSomethingElse b[0], b[1]

Dies kann mit Splats kombiniert werden

[first, rest..., last] = doSmth()
metalim
quelle
1
Es kann besser sein, wenn Sie jeden Tipp in eine separate Antwort trennen :)
Beta Decay
@BetaDecay Deal.
Metalim
2

Kurzschlussauswertung anstelle des ternären Bedieners

CoffeeScript verfügt nicht über den ternären Operator von JavaScript. Manchmal kann jedoch stattdessen ?die Funktionalität der Kurzschlussbewertung verwendet werden:

foo = a && b || c

# Long form:
foo = if a then b else c

Ist etwas äquivalent zu in JavaScript:

foo = a ? b : c

Es funktioniert nicht , wenn b ein falscher Wert ist (oder auswerten kann), wie z 0.

rink.attendant.6
quelle
2

Integer Division Operator //

Spart bis zu 10 Bytes, da beim Teilen keine Floor-Nummern erforderlich sind.

Verwenden des //Operators:

foo = 61/3                 # foo = 20.333333333333332
foo = Math.floor 61/3      # foo = 20 (15 bytes)
foo = 61/3|0               # foo = 20 (6 bytes)
foo = 61//3                # foo = 20 (5 bytes)

Im Vergleich zu JavaScript:

foo = 61/3                // foo = 20.333333333333332
foo = Math.floor(61/3)    // foo = 20 (16 bytes)
foo = 61/3|0              // foo = 20 (6 bytes)
rink.attendant.6
quelle
(61/3|0)funktioniert genauso gut für Vanille JS.
ETHproductions
@ETHproductions Ich habe es in den Beitrag hinzugefügt, um den Unterschied in der Bytesize anzuzeigen
rink.attendant.6
//ist eigentlich a .floor(), also funktioniert es anders für negative Zahlen : foo = -61//3 # -21, whilefoo = -61/3|0 # -20
metalim
Sie können auch //1für einen einfachen Boden verwenden.
Cyoce
1

Lassen Sie nach Möglichkeit Klammern weg

func1 func2 func3(a),func3 b

#instead of

func1(func2(func3(a),func3(b))
metalim
quelle
1

Nicht nullaber möglicherweise falsy ( 0, NaN, "", false, etc.)

Wenn Sie überprüfen müssen, ob eine Variable definiert ist und nicht null, verwenden Sie das nachfolgende Fragezeichen:

alert 'Hello world!'if foo?

Kompiliert zu:

if (typeof foo !== 'undefined' && foo !== null) {
    alert('Hello world!')
}

Dies gilt wahrscheinlich nicht für viele Code-Golf-Einträge, kann jedoch nützlich sein, wenn Sie von einer Null, einer falschen, einer leeren Zeichenfolge oder einem anderen falschen Wert unterscheiden müssen.

rink.attendant.6
quelle
1

Potenzierungsoperator **

Spart 9 Bytes:

foo = 2**6
# foo = 64

Im Vergleich zu JavaScript:

foo = Math.pow(2,6)
// foo = 64
rink.attendant.6
quelle
Für Zweierpotenzen ist dies irrelevant, da 1<<xes gleich ist2**x
Stan Strum
1

Arrays suchen

Speichern Sie ungefähr 8 Bytes, wenn Sie nur überprüfen möchten, ob sich ein Element in einem Array befindet. Sie können den inOperator verwenden.

y = x in['foo', 'bar', 'baz']

Im Vergleich zu Alternativen in JavaScript:

y = ~['foo', 'bar', 'baz'].indexOf(x)   // ES5, returns Number
y = ['foo', 'bar', 'baz'].includes(x)   // ES7, returns boolean
y = ~$.inArray(x,['foo', 'bar', 'baz']) // jQuery, returns Number

In dem seltenen Fall, dass Sie den Index des Elements benötigen, funktioniert dieser Trick jedoch nicht für Sie.

rink.attendant.6
quelle
Gleiches gilt für die Suche nach Zeichenfolgen oder das Erkennen, ob sich ein Zeichen in einem bestimmten Satz befindet:b = c in'|-+'
metalim
1

Platz macht Spaß. Der Speicherplatz ist für das Aufrufen von Funktionen von Bedeutung

a=b[i]  # get i-th element of array b
a=b [i] # a = b( [i] ) # pass [i] to function b

m=n+k   # simple math
m=n +k  # m = n( +k ) # convert k to number and pass to function n
m=n -k  # m = n( -k ) # pass -k to function n
m=n + k # simple math again


a(b c)+d   # a( b( c ) ) + d
a (b c)+d  # a( b( c ) + d )
a (b c) +d # a( b( c )( +d ) )
metalim
quelle
0

Verwenden Sie Splats

obj.method a, params...

# instead of

obj.method.apply obj, [a].concat params

# especially useful with new objects

obj = new Obj a, params...

# alternative is complicated, unreadable and not shown here.
metalim
quelle
0

Sichere Accessoren: ?.undfunc? args...

Existenzieller Operator ?hat viele Formen und Verwendungen. Abgesehen davon, dass nur geprüft wird, ob eine Variable festgelegt ist, können Sie auf Objektmethoden und -eigenschaften zugreifen, ohne vorher zu prüfen, ob das Objekt null ist:

obj.property?.method? args...

wird obj.property.method args...nur ausgeführt, wenn obj.propertyund obj.property.methoddefiniert sind und nicht null.

Nützlich, wenn Sie mehrere spärliche Arrays gleichzeitig durchlaufen:

arr1[i]?.prop = arr2[i]?.method? args... for i in[0..99]
metalim
quelle