Sitemap
Calidae Blog

El Blog de Calidae

Cool Javascript 7: comma operator

3 min readNov 16, 2017

--

L’objectiu d’aquesta sèrie de posts és recomanar bones pràctiques a l’hora d’escriure Javascript. Bones pràctiques que no han de ser un game changer ni ens han de convertir en el Messi del codi, sinó simplement millorar-ne una mica la robustesa, legibilitat i mantenibilitat.

Avui us volia parlar del comma operator. És un exemple claríssim de petita funcionalitat digne de cool Javascript.

Pel nom queda bastant clar, no? És un operador en forma de coma.

Però….

Què *no* és el comma operator?

No totes les comes que veiem són un operador. Javascript fa servir comes en moltes estructures de dades i en altres construccions del llenguatge. A saber:

// Tot això NO són comma operators:const x = 0, y = 0
const arr = [4, 5, 6, 7, 8, 9]
const obj = { b: 1, c: 2 }
const sum = (a, b) => a + b
add(3, 5)
const { b, c } = obj
const [d, e] = [0, 1]
import { func1, func2 } from 'funcs'
export { func1, func2 }

En tots aquests casos fem servir comes però no tenen res a veure amb el comma operator.

Val, entès. Parlem del que mola, doncs:

Què és el comma operator?

La definició oficial diu que el comma operator avalua cada un dels seus operadors d’esquerra a dreta i retorna el valor de l’últim operand.

Resulta que probablement hàgim estat utilitzant el comma operator fins ara sense saber-ho:

for (let x = 0, y = 50; x <= 100; x++, y--) {
// ...
}

Oju que no us enganyi, el comma operator el veiem al tercer operador del for. El for només pot tenir una expressió per assignació, limit i actualització, i aquí aprofitem el poder del comma operator per fer 2 actualitzacions en una sola expressió: incrementem X i decrementem Y.

Dit d’una altra manera, això és completament correcte:

return a++, b

Incrementa el valor de A i retorna B. Només retorna B.

Ok, ja sé què és. Quan ho puc fer servir?

Mira, jo he trobat alguns casos pràctics. Per exemple, si tenim una arrow function molt senzilla

const func = x => x+3

i volem saber el valor de X fent un console.log:

const func = x => (console.log(x), x+3)

Noti’n-se els parèntesis.

Get Adrià Fontcuberta’s stories in your inbox

Join Medium for free to get updates from this writer.

(tot i que si vols fer-ho encara millor, ololog is the way to go. No només per l’styling, sinó perquè logueja un valor i el retorna, de manera que es pot encadenar sense fer res més: func = x => log(x) + 3).

La màxima utilitat que li trobo és al debuggar, tant en el cas anterior com en altres. Per exemple, si evitem els {} en expressions que no els necessiten:

// Si tenim això...
if (test) val = doSomething()
// Sense el comma operator hem d'escriure els {} que volíem evitar.
// Kinda miss the point, right?

if (test) {
val = doSomething()
console.log('val:', val)
}

// Amb el comma operator és molt més net i ràpid
if (test)
val = doSomething(),
console.log('val:', val)

Què més? En combinació amb l’if ternari és molt potent:

triesLeft ?
(triesLeft--, tryAgain()) :
(warnUserNoMoreTries(), Finish())

triesLeft és un comptador d’intents. M’entre ens quedin intents, reintantem la operació que sigui i en decrementenm un. Quan no en quedin, avisa l’usuari i finalitzem el programa.

En sensillo:

(i > 0) ? (i--, doSomething()) : doSomethingElse()

Functional programming

El comma operator és útil quan treballem utilitzant el chaining habitual de la programació funcional. Em feia mandra escriure un exemple i l’he robat a Stack Overflow:

const actions = _.chain(options)
.pairs()
.map(createActionPromise)
.reduce((st, p) => (st[p[0]] = p[1], st), {})
.value()

Sense el comma operator hauríem de desplegar el reduce i perdre la consistència que ofereix aquest format d’escriptura.

Showing off

Què passa pythoneros, que dieu que mola treballar sense punts i comes? En el fons, el for només té un operador gràcies al comma operator:

let curr = 0, next = 1, tmpfor (let i = 0; i < 10; ++i)
tmp = curr + next,
curr = next,
next = tmp,
console.log('Fibonacci', i, '=', curr)

i una segona versió:

for (
let i = 2, r = [0,1];
i < 10;
r.push(r[i-1] + r[i-2]), i++
)

console.log(r)

--

--

Adrià Fontcuberta

Written by Adrià Fontcuberta

Words matter – Software product development, Front-end, UX, design, lean, agile and everything in between. https://afontcu.dev