Skip to content

General Javascript Golfing Tricks

Paul "Joey" Clark edited this page Aug 8, 2018 · 15 revisions

Looping

A reverse for loop is shorter than a forwards for loop:

for(i=0;i<10;i++)...   // before
for(i=10;i--;)...

A for loop can use a , instead of {} to do multiple things inside the body:

for(i=10;i--;){thing1();thing2()}   // before
for(i=10;i--;)thing1(),thing2()

You can save a further char by moving the last thing (or more) inside the for:

for(i=10;i--;)thing1(),thing2()   // before
for(i=10;i--;thing2())thing1()

Do you need to loop from 0 to 2 or less? You can use for ... in

for(i=0;i<3;i++)...
// becomes
for(i in 'omg')...
// but looping backwards is still shorter (if you can)
for(i=3;i--;)...

If you want to loop the values of a string:

for(p of '🦡🍄🐍')console.log(p)

Instead of two nested loops, you can often use one loop, and get the original numbers using floored division and modulus:

// Before
for(i=128;i--;)for(j=32;j--)draw(i,j)
// After
for(k=4096;i--;)draw(k/32|0,k%32)

And if the inner loop happens to be a power of two (such as 32 === 2**5), then you can get the flooring for free by using a bitshift for division:

// After
for(k=4096;i--;)draw(k>>5,k&31)

Statement separators

Usually in Javascript we use ; to separate statements. But when golfing, we can save space by using , or |

if(x){thing1();thing2()}
if(x)thing1(),thing2()

// But commas won't work in arrow functions, so use | or & there

f=(a,b)=>{thing1(a,b);thing2(b,a)}
f=(a,b)=>thing1(a,b)|thing2(b,a)     // These both evaluate thing2()
f=(a,b)=>thing1(a,b)&thing2(b,a)     // regardless of the result of thing1()

The reason for the difference is that the body of an if is a statement, but the body of a lambda function is an expression.

Dictionaries (hashtables)

You can use just about any existing Javascript object as a dictionary if you need to, to avoid initialising your own.

onclick=e=>{a=[],a[9]=5}
onclick=e=>{e[9]=5,a=e}

A dictionary can be used as a cheap array, but it won't give you .length or any Array methods.

With

Four times x. can be shortened using with(x)...

Need to call a function multiple times, but it's a member of another object?

You can't do F=x.fillRect;F();F() because F won't see its context object x.

But you can do:

x.F=x.fillRect;x.F(X,Y+7,3,3);x.F(187,Y+C(X/39)*29,5,20);x.F(0,Y-S(X/29)*22,5,20)

Alternatively, or additionally, try using the with operator.

with(x)F(),F(),F(),F()

Experiment

Some of the Javascript API functions have really long names. If you are using more than ~5 of these, then these functions might help. They let us search for properties using a regexp.

/** p(object, regexp) = find key in object */
p=(o,r)=>{for(k in o)if(k.match(r))return ok}
/** P(object, regexp) = get property from object */
P=(o,r)=>o[p(r)]

f=(o,r)=>p(o,r).bind(o)

If I am using the same o repeatedly, then I might remove the o argument from those functions, and instead set it as a global before calling p or P.

So now, instead of XMLHttpRequest ......................... ?

Logic

You can not do foo&&bar=1 but you can do foo?bar=1:0

Remember that | is greedy but % is not. Other bitwise operations are also greedy (&, <<, >>, ^).

If you need to floor and then modulus, instead of (x|0)%y you can use ~~x%y

Emojis

You can access most Unicode chars directly from a string: "abc"[k]

But that doesn't work so well with emojis, because emojis are two characters each, so you only get half the code!

However, you can copy emojis into an array, and extract from that: [...'🐸🌷☁️️'][k]

This only saves space if you are using 3 or more emojis.

Extreme Javascript Tricks

If you need to call a function many times, you can override the valueOf of an object, and trigger the interpreter to call it without having to use any ()s in your own code. (demo, slide)

// Before
r=Math.random;x.arc(r(),r(),r(),r(),r(),r())
// After
T.valueOf=Math.random;x.arc(T,T,T,T,T,T)

Explanation: When an object is used in an algebraic expression, before coercion its valueOf function is called by the interpreter.