Dicas para jogar golfe no CoffeeScript

8

Quais truques você conhece para diminuir o código do CoffeeScript?

CoffeeScript é uma linguagem que é compilada em JavaScript ("transpila" para o ES3, para ser exato). A regra de ouro é "É apenas JavaScript", o que significa que não há sobrecarga no tempo de execução. A maioria das dicas e truques para JavaScript também se aplica.

Como efeito colateral, isso também significa: desenvolvedores provenientes de JavaScript (inclusive eu) tendem a usar construções JavaScript em vez de alternativas mais curtas ao CoffeeScript.

Este tópico enfoca dicas específicas para o CoffeeScript.

Links para tópicos relacionados:

Dicas para jogar golfe em JavaScript

Dicas para jogar golfe no ECMAScript 6 e acima

metalim
fonte
O coffeescript pode ser compilado no ES6? É compatível?
haskeller orgulhoso
@proudhaskeller Compila no ES3 em geral, com uma exceção: se você yieldcompila no gerador ES6. Caso contrário, ele tenta ser o mais compatível possível com o navegador.
metalim

Respostas:

3

Use atribuições de desestruturação, se os elementos da estrutura forem usados ​​com frequência

Por exemplo. obter elementos da primeira matriz de argumentos

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]

Isso pode ser combinado com splats

[first, rest..., last] = doSmth()
metalim
fonte
1
Pode ser melhor se você separar cada dica em uma resposta separada :)
Decay Beta
@BetaDecay Deal.
metalim
2

Avaliação de curto-circuito no lugar do operador ternário

O CoffeeScript não possui o operador ternário do JavaScript ?, no entanto, às vezes , a funcionalidade da avaliação de curto-circuito pode ser usada:

foo = a && b || c

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

É um pouco equivalente ao JavaScript:

foo = a ? b : c

Ele vai não funcionará se b é (ou pode avaliar a) um valor Falsas tais como 0.

rink.attendant.6
fonte
2

Operador de divisão inteira //

Economiza até 10 bytes, evitando a necessidade de incluir números ao dividir.

Usando o //operador:

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)

Comparado ao 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
fonte
(61/3|0)funciona tão bem para o vanilla JS.
ETHproductions
@ETHproductions eu adicionei-lo para o cargo para indicar a diferença de bytesize
rink.attendant.6
//é realmente a .floor(), então funciona de maneira diferente para números negativos foo = -61//3 # -21foo = -61/3|0 # -20
:,
Você também pode usar //1para um piso plano.
precisa saber é
1

Omita parênteses quando possível

func1 func2 func3(a),func3 b

#instead of

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

Não null, mas possivelmente Falsas ( 0, NaN, "", false, etc.)

Se você precisar verificar se uma variável está definida e não null, use o ponto de interrogação à direita:

alert 'Hello world!'if foo?

Compila para:

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

Isso provavelmente não se aplica a muitas entradas de código de golfe, mas pode ser útil se você precisar distinguir de um valor zero, falso, cadeia vazia ou outro valor falso.

rink.attendant.6
fonte
1

Operador de exponenciação **

Salva 9 bytes:

foo = 2**6
# foo = 64

Comparado ao JavaScript:

foo = Math.pow(2,6)
// foo = 64
rink.attendant.6
fonte
Para potências de dois, isso é irrelevante, pois 1<<xé igual a2**x
Stan Strum
1

Procurando matrizes

Salve aproximadamente 8 bytes se quiser verificar se um elemento está em uma matriz, você pode usar o inoperador.

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

Comparado com alternativas em 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

No entanto, no caso raro de você precisar do índice do elemento, esse truque não funcionará para você.

rink.attendant.6
fonte
Mesmo se aplica para a busca de cordas, ou detectar se o personagem está em jogo específico:b = c in'|-+'
metalim
1

O espaço é divertido. O espaço é significativo para chamar funções

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
fonte
0

Use 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
fonte
0

Acessadores seguros: ?.efunc? args...

O operador existente ?possui muitas formas e usos. Além de apenas verificar se a variável está definida, você pode acessar métodos e propriedades do objeto sem verificar previamente se o objeto é nulo:

obj.property?.method? args...

será executado obj.property.method args...apenas se obj.propertye obj.property.methodestiver definido e não for nulo.

Útil se você repetir várias matrizes esparsas ao mesmo tempo:

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