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.
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
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…
Román Cortés » Furbee - My Js1k Spring ‘13 entry
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;
Thanks Oscar. I’ve updated the list with your trick. Pretty much useful!
What’s up, its pleasant article on the topic of media print, we
all know media is a fantastic source of facts.
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…?
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
Hi there to every body, it’s my first visit of this web site; this blog contains remarkable
and really excellent information for readers.
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
So did they reprice their own liquidity immediately after the event?
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!
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
Can also clear canvas by chaining onto a set variable….
canvas.width|=x=1
Detective Moji postmortem : a javascript game in just 1024 bytes | M42 Studio