Javascript Golfing

All examples assume working with the shim. Some tricks are good only if no semantic compression is used after (i.e. JSCrush), just minifying. Others are compatible with crushing. At the end, is a funny game of trial and checking to reach the lowest size depending on the code structure.

Remove var statement

var j=0;  // before
j=0;      // after

In most cases all variables can be global and var statement can be removed from variable declaration. This saves 4 chars for every one. Be careful with side effects from recursive function calls if they manipulate global vars.

Tweak for loops

p;
while (q) {
  ...
  r;
}            // before
for(p;q;r)   // after

The for-loop can be used in non-standard ways, saving lot of chars (4 in the example).

Initialization chain

i=1;
j=1;   // before
i=j=1; // after

Values can be assigned in chain when several variables must be assigned to same one. 2 chars saved.

Implicit casting

i="10";
j="20";

k=parseInt(i)+parseInt(j);  // before
k=i- -j;                    // after

k=parseInt(i);              // before
k=i|0;                      // after
k=~~i;                      // after (alternative)

This is one of the most powerful byte-saving technique. Don’t check your types, just use them as they are. The example shows how to cast out two strings into a sum, saving 18 chars. The i|0 method saves 8 chars against the standard parseInt().

Remove semicolons

while (p) { q; } // before
while (p) { q } // after

Javascript has automatic semi-colon insertion. Get rid of using them in most of the cases.

Increment / Decrement operators

p=p+1; // before
p++;   // after

This is self-explanatory. 2 chars saved.

Short-circuit operators

if (p) p=q;  // before
p=p&&q;      // after

if (!p) p=q; // before
p=p||q;      // after

These operators reduce the script size rather that using if statements like the ones in the examples.

Creating repetitive strings

str="                              "; // before
str=Array(31).join(" ");              // after

13 chars saved in the example by using the Array method.

Avoid braces by using commas

if (i<10) {m+=5;n-=3} // before
if (i<10) m+=5,n-=3;  // after

Shorter sentence when using commas (1 char saved).

 Compressed iterative loop

i=10;while(i--);  // before
for(i=10;i--;);   // after

This kind of loop structure is used very often. Second form is one character shorter.

Use color names

a.fillStyle="rgb(255,0,0)";  // before
a.fillStyle='red';           // after

Most color names declarations are usually shorter than the rgb() equivalent. Check Doug Crockford’s color chart for reference.

Shorten repetitive function calls

i=[Math.random()*2,Math.random()*3,Math.random()*4); // before
r=Math.random;i=[r()*2,r()*3,r()*4];                 // after

i=Math.cos(10)*Math.cos(20)*Math.cos(30);
j=Math.sin(10)*Math.sin(20)*Math.sin(30);
k=Math.random(10)*Math.random(20)*Math.random(30);    // before

with(m=Math)C=cos,S=sin,R=random;
i=m.C(10)*m.C(20)*m.C(30);
j=m.S(10)*m.S(20)*m.S(30);
k=m.R(10)*m.R(20)*m.R(30);                            // after

Saves lot of chars when the script contains many function calls. 20 chars shorter in the second example.

Variable init inside loop

for(j=0;p=1,j<n;j++) // before
for(j=0;p=j<n;j++)   // after

If a variable initialization to 1 is needed inside a loop like in the example, it can be assigned to the loop condition (since is true during loop execution). The variable will get the true value in this case.

Declaring array of strings

f=['Monday','Tuesday','Wednesday','Thursday','Friday']; // before
f='Monday0Tuesday0Wednesday0Thursday0Friday'.split(0);  // after

This is useful when the data size is bigger, more chars saved. Bonus by using split(0) instead of split('c').

 Anonymous function for drawing

function d(){ ... }setInterval(d,9);  // before
setInterval(function(){ ... },9)      // after

If the script uses a setInterval() method to draw animation, this technique saves four chars. Bonus improvement by removing the function completely (take care of special chars inside the quotes):

setInterval("do this",9);

Embed functionality in function calls

i=j<<1+i;x(i,1); // before
x(i=j<<1+i,1);   // after

Save chars by processing stuff within (unused) arguments.

Re-use variables where possible

setTimeout(function(){for(var i=10;i--;)... }, j) // before
setTimeout(function(){for(j=10;j--;)... }, j)     // after

Checking the whole script and using again same variable when no longer needed saves chars.

Use an array to swap variables

var i=1,j=2,k;k=i;i=j;j=k // before
var i=1,j=2;i=[j,j=i][0]  // after

Clever technique to avoid declaring another variable.

Flooring positive numbers

i=Math.floor(Math.random()*10) // before
i=0|Math.random()*10           // after
i=~~Math.random()*10           // after (alternative)

Implicit casting makes this possible.

Round positive numbers

Math.round(a) // before
a+.5|0        // after

Use scientific AeB format for large constants

million=1000000 // before
million=1e6     // after

Exploit the “falsiness” of 0

a==1||console.log("not one") // before
~-a&&console.log("not one")  // after

Use XOR operator to check if numbers are not equal

if (i!=123) // before
if (i^123)  // after

When having several if conditions in chain checking for different numbers, this technique can be combined, saving more chars.

Generate random numbers with current date

i=0|Math.random()*100 // before
i=new Date%100        // after

Warning, if used in a fast loop the milliseconds will not change.

Use coercion to build strings with commas in them

"rgb("+(x+8)+","+(y-20)+","+z+")"; // before
"rgb("+[x+8,y-20,z]+")";            // after

"rgb(255,"+(y-20)+",0)";           // before
"rgb(255,"+[y-20,"0)"];            // after

Pretty useful for RGB declarations.

Test array length

if(array.length>1) // before
if(array[1])       // after

Create booleans in a shorter way

[true,false] // before
[!0,!1]      // after

In general you can get away of actual booleans by using 0 and 1.

Omit () on new calls

now=+new Date() // before
now=+new Date   // after

Omit new keyword when possible

l=new Regexp(".",g) // before
l=Regexp(".",g)     // after

Some constructors don’t require the new keyword.

The return statement can be used without spaces

return .01;  // before
return.01;   // after

return ['foo',42]; // before
return['foo',42];  // after

When returning anything but a variable, there’s no need to use a space after.

The canvas context hash trick

a.beginPath
a.fillRect
a.lineTo
a.stroke
a.transform
a.arc                                  // before

for(Z in a)a[Z[0]+(Z[6]||Z[2])]=a[Z];
a.ba
a.fc
a.ln
a.sr
a.to
a.ac                                   // after

If the demo uses lot of calls to the canvas drawing functions, this method reduce all the name methods to short calls, reducing the overall chars usage. In some cases, a modified version of the hash can be used:

for($ in a)a[$[0]+$[6]]=a[$];

But test it carefully in all browsers. This one has a more limited function selection, with different performance in each browser.

Setting canvas width/height also clears it

c.width=c.height=o;
...
c.clearRect(0,0,o,o);   // inside animation loop
...                     // before

...
c.width=c.height=o;     // inside animation loop
...                     // after

This saves one complete sentence if the demo has animation with clearing the canvas on every frame.

Get current status of multiple keys pressed

k = [];
onkeydown = function(x) {k[x.which]=1};
onkeyup = function(x) {k[x.which]=0};

With this method, the array k always contains the keycodes pressed/released.

13 thoughts on “Javascript Golfing

  1. Shorten Repetitive Calls
    instead of assigning variables with the ‘with’ you can also just use the with (but be careful)
    with(Math){
    r=random
    i=cos(10)*cos(20)*cos(30);
    j=sin(10)*sin(20)*sin(30);
    k=r(10)*r(20)*r(30);
    }

    Implicit Casting/Flooring Positive Numbers
    ‘~~’ can also be used to floor positive numbers (and ciel negatives) and also cast

    Create Booleans in a Shorter Way
    it’s worth mentioning that in general you can get away with using 0 and 1 instead of actual booleans

    Canvas Context Hash trick
    in some cases, a modified version (for($ in a)a[$[0]+$[6]]=a[$];) can be used, which has a more limited function selection (can be modified for specific use). Also the use of ‘with’ can be extremely powerful here. See http://www.zolmeister.com/2013/02/my-js1k-submission-flurry.html for how I use ‘with’ extensively within my code.

    *note, String Coercion has typo, missing a ‘+’ in first example

  2. Hi Zoli,

    Thanks a lot for your remarks! Post updated.

    PS: The hash trick is really risky, specially with Safari. The initial one posted is working fine with all 3 browsers today in my demo, but who knows in future versions…

  3. Román Cortés » Furbee - My Js1k Spring ‘13 entry

  4. By the way, the bit-or equals Math.floor only with 32-bit positive numbers.

    I tend to use several ‘with’ surrounding my code, including with(Math), this saves five letters on each Math call (Math and the point)

    And a very small way to get current status of multiple keys pressed:

    k = [];
    onkeydown = function(x) {k[x.which]=1};
    onkeyup = function(x) {k{x.which]=0};

    To get codes for common keys, simply add document.title = x.which;

  5. What’s up, its pleasant article on the topic of media print, we
    all know media is a fantastic source of facts.

  6. Great article on JS golf, (one of my favorite pastimes!)… Just one question… You mention the use of ~~i and i|0 as a substitute for parseInt(i)… I’ve noticed this works great with 32-bit numbers… but are there any golfed alternatives for parseInt() for 64-bit numbers…?

  7. I see you share interesting content here, you can earn some additional cash, your website has
    big potential, for the monetizing method, just type in google – K2 advices
    how to monetize a website

  8. I read a lot of interesting content here. Probably you
    spend a lot of time writing, i know how to save you a lot of work, there is an online tool that creates high
    quality, SEO friendly posts in seconds, just type in google – laranitas
    free content source

  9. Hey there! I’m at work browsing your blog from my new iphone!
    Just wanted to say I love reading through your
    blog and look forward to all your posts! Carry
    on the outstanding work!

  10. Hello admin, i must say you have hi quality posts here.

    Your website should go viral. You need initial traffic only.
    How to get it? Search for: Mertiso’s tips go viral

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>