Consejos para jugar golf en CoffeeScript

8

¿Qué trucos sabes para acortar el código CoffeeScript?

CoffeeScript es un lenguaje que compila en JavaScript ("transpila" en ES3, para ser exactos). La regla de oro es "Es solo JavaScript", lo que significa que no hay sobrecarga de tiempo de ejecución. La mayoría de los consejos y trucos de JavaScript también se aplican.

Como efecto secundario eso también significa: los desarrolladores que vienen de JavaScript (incluido yo mismo) tienden a usar construcciones de JavaScript en lugar de alternativas más cortas de CoffeeScript.

Este hilo se centra en consejos específicos para CoffeeScript.

Enlaces a temas relacionados:

Consejos para jugar golf en JavaScript

Consejos para jugar golf en ECMAScript 6 y superior

metalim
fuente
¿Se puede compilar coffeescript a ES6? ¿Es compatible?
orgulloso Haskeller
@proudhaskeller Se compila en ES3 en general, con una excepción: si usted yield, se compila en el generador ES6. De lo contrario, intenta ser lo más compatible posible con el navegador.
metalim

Respuestas:

3

Use asignaciones de desestructuración, si los elementos de la estructura se usan con frecuencia

P.ej. obtener elementos de la primera 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]

Esto se puede combinar con símbolos

[first, rest..., last] = doSmth()
metalim
fuente
1
Puede ser mejor si separa cada consejo en una respuesta separada :)
Beta Decay
@BetaDecay Deal.
metalim
2

Evaluación de cortocircuito en lugar de operador ternario

CoffeeScript no tiene el operador ternario de JavaScript ?, sin embargo, la funcionalidad de evaluación de cortocircuito a veces se puede utilizar en su lugar:

foo = a && b || c

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

Es algo equivalente a en JavaScript:

foo = a ? b : c

Será no funciona si b es (o puede evaluar a) un valor Falsy como 0.

rink.attendant.6
fuente
2

Operador de división entera //

Ahorra hasta 10 bytes al evitar la necesidad de números de piso al dividir.

Usando el //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)

En comparación con 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
fuente
(61/3|0)funciona igual de bien para vanilla JS.
ETHproductions
@ETHproductions Lo he agregado a la publicación para indicar la diferencia en bytesize
rink.attendant.6
//es en realidad a .floor(), por lo que funciona de manera diferente para números negativos:, foo = -61//3 # -21mientras quefoo = -61/3|0 # -20
metalim
También se puede usar //1para un piso liso.
Cyoce
1

Omitir paréntesis cuando sea posible

func1 func2 func3(a),func3 b

#instead of

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

No nullpero posiblemente Falsy ( 0, NaN, "", false, etc.)

Si necesita verificar si una variable está definida y no null, use el signo de interrogación final:

alert 'Hello world!'if foo?

Compila a:

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

Esto probablemente no se aplicará a muchas entradas de golf de código, pero podría ser útil si necesita distinguir de un cero, falso, cadena vacía u otro valor falso.

rink.attendant.6
fuente
1

Operador de exponenciación **

Guarda 9 bytes:

foo = 2**6
# foo = 64

En comparación con JavaScript:

foo = Math.pow(2,6)
// foo = 64
rink.attendant.6
fuente
Para potencias de dos, es irrelevante que 1<<xes igual a2**x
Stan Strum
1

Buscando matrices

Ahorre aproximadamente 8 bytes si solo desea verificar si un elemento está en una matriz, puede usar el inoperador.

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

En comparación con las alternativas en 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

Sin embargo, en el raro caso de que necesite el índice del elemento, este truco no funcionará para usted.

rink.attendant.6
fuente
Lo mismo se aplica para buscar cadenas o detectar si el carácter está en un conjunto específico:b = c in'|-+'
metalim
1

El espacio es divertido. El espacio es importante para llamar a funciones

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

Usa símbolos

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

Accesores seguros: ?.yfunc? args...

El operador existencial ?tiene muchas formas y usos. Además de verificar si la variable está configurada, puede acceder a los métodos y propiedades del objeto sin verificar previamente si el objeto es nulo:

obj.property?.method? args...

se ejecutará obj.property.method args...solo si obj.propertyy obj.property.methodestán definidos y no son nulos.

Útil si itera sobre varias matrices dispersas al mismo tiempo:

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