Code Golfing Tips
Code Golfing Tips
Ciprian on Tuesday, August 9, 2022 in JavaScript Arrays & Objects, Methods, Events and Scopes
Last modified on Monday, August 29, 2022
If you are into JavaScript code golfing or just looking to minify your code, here’s a collection of tips
and tricks to help you understand JavaScript intricacies and make your code shorter.
Table of Contents
What is JavaScript Golfing?
Why and when should minified code be used?
Arguments
Function Variable Arguments Shorthand
Use one-letter positional arguments, in alphabetical order
Test argument presence instead of length
Embed functionality within arguments
Reuse parenthesis of the function call
setInterval and setTimeout hacks
Variables
Declaring variables Shorthand
Implicit Casting
Use placeholder arguments instead of var
Re-use variables where possible
Assign wherever possible
Use an array to swap variables
Choose small data format
Null, Undefined, Empty Checks Shorthand
Loops
Fancy For Loops
Combine nested for loops
JavaScript foreach Loop Shorthand
Omit loop bodies
Use for over while
Use index presence to iterate arrays of truthy items
Use for..in with assignment to get the keys of an object
Use reverse loops where possible
Use both for body and counting expression for multiple operations
for..in will not iterate over false – use this to trigger iteration
Decimal base exponents
Operators
Understand operator precedence
Understand bitwise operator hacks
Assignment Operators Shorthand
Use ~ with indexOf to test presence
Use , to chain expressions on one conditional line
Use []._ instead of undefined
Remove unnecessary space after an operator
Double Bitwise
Numbers
Integer division by the power of two
Math.floor()
Use ~~ and 0| instead of Math.floor for positive numbers
Use A + 0.5 | 0 instead of Math.round for positive numbers
Use AeB format for large denary numbers
Use A<<B format for large binary numbers
Use 1/0 instead of Infinity
Use division instead of isFinite()
Exploit the “falsiness” of 0
Use ~ to coerce any non-number to -1
Check if variables have the same sign
Use ^ to check if numbers are not equal
Use number base for character to number conversion
Use current date to generate random integers
Strings
Prefer slice over substr over substring
Split using ` “ `
Split using spread Operator
Split using 0
Use the little-known .link method
Use .search instead of .indexOf
Use .replace or .exec for powerful string iteration
Use Array to repeat a string
CharAt Shorthand
Conditionals
If true … else Shorthand
If Presence Shorthand
Short IF’z
Avoid braces by using commas
Lookup Tables Shorthand
Comparison Returns
Use && and || where possible
Switch Nightmare
XOR Swap
Toggle between two values
Coercion to test for types
Type-specific methods to test for types
Arrays
Using the Spread operator
Test array length
Use elision
Use coercion to do .join(‘,’)
String coercion with array literal []
Use coercion to build strings with commas in them
Use Arrays as Objects
Test if Array has Several Elements
Object Array Notation Shorthand
Associative Array Notation Shorthand
Regular Expressions
RegExp Object Shorthand
Use shortcuts
Denormalize to shorten
Don’t escape
eval() for a regexp literal can be shorter than RegExp()
eval() around String.replace() instead of callback
Booleans
Use ! to create booleans
Functions
Use Array-Access for repeat function calls
Shorten repetitive function calls
Short Function Calling
Shorten function names
Use named functions for recursion
Use named functions for saving state
Omit () on new calls w/o arguments
Omit the new keyword when possible
The return statement
Use the right closure for the job
Shorten functions with Arrow Declaration
One-liners
Embed functionality in function calls
Delimiters
Minification and compression
Sources for this list
What is JavaScript Golfing?
JavaScript golfing is the process of writing the smallest amount of JavaScript code to do something
awesome. It tests your ability to reduce, reuse, and recycle for the purpose of achieving the tiniest
footprint possible.
Why and when should minified code be used?
The purpose of code golfing is to test one’s abilities, during challenges. That said, you should not use
techniques like this in your normal code, as it compromises readability. Ideally, you should only use
these tricks during a challenge.
Arguments
Function Variable Arguments Shorthand
Object literal shorthand can take a little getting used to, but seasoned developers usually prefer it
over a series of nested functions and variables.
// Longhandfunction myFunction(myString, myNumber, myObject, myArray, myBoolean) {
// do something...
}
x += y; // Result 15
x -= y; // Result 5
x *= y; // Result 50
x /= y; // Result 2
x %= y; // Result 0
Use ~ with indexOf to test presence
hasAnF="This sentence has an f.".indexOf("f")>=0 // before
hasAnF=~"This sentence has an f.".indexOf("f") // after
// Longhandif (str.indexOf(ndx) == -1) {
// Char not found
}
// Shorthandif (~str.indexOf(ndx)) {
// Char not found.
}
Use , to chain expressions on one conditional line
with(document){open();write("hello");close()}with(document)open(),write("hello"),close()
Use []._ instead of undefined
""._, 1.._ and 0[0] also work, but are slower. void 0 is faster than undefined but longer than the
alternatives.
Remove unnecessary space after an operator
Whitespace isn’t always needed after an operator, and may sometimes be omitted:
typeof [] // beforetypeof[] // after
Double Bitwise
The double bitwise trick provides us with some pretty nifty shorthand tricks.
// Longhand
Math.floor(4.9) === 4 // true
// Shorthand~~4.9 === 4 // true
Numbers
Integer division by the power of two
// Longhand
Math.floor(x/2);
// Shorthand
x>>1;
Math.floor()
// Longhand
Math.floor(4.9); // 4
// Shorthand
4.9 | 0; // 4~~4.9; // 4
Use ~~ and 0| instead of Math.floor for positive numbers
Both of these operator combos will floor numbers (note that since ~ has lower precedence than |,
they are not identical).
rand10=Math.floor(Math.random()*10) // before
rand10=0|Math.random()*10 // after
If you are flooring a quotient where the divisor is a multiple of 2, a bit-shift-right will perform both
operations in one statement:
Math.floor(a/2) // before
a>>1 // after
Math.floor(a / 4) // before
a>>2 // after
Use A + 0.5 | 0 instead of Math.round for positive numbers
Math.round(a) // before
a+.5|0 // after
Also, for negative number just change +.5|0 to -.5|0
Math.round(-a) // before-a-.5|0 // after
Use AeB format for large denary numbers
This is equivalent to A*Math.pow(10,B).
million=1000000 // before
million=1e6 // after
Use A<<B format for large binary numbers
This is equivalent to A*Math.pow(2,B).
color=0x100000 // before
color=1<<20 // after
Use 1/0 instead of Infinity
It’s shorter. Besides, division by zero gets you free internet points.
[Infinity,-Infinity] // before
[1/0,-1/0] // after
Use division instead of isFinite()
Division of 1 by any finite number results nonzero “truthy” value.
if(isFinite(a)) // beforeif(1/a) // after
Exploit the “falsiness” of 0
When comparing numbers, it’s often shorter to munge the value to 0 first.
a==1||console.log("not one") // before~-a&&console.log("not one") // after
Use ~ to coerce any non-number to -1
Used together with the unary -, this is a great way to increment numerical variables not yet initialized.
i=i||0;i++ // before
i=-~i // after
It can also be used to decrement a variable by flipping around the negation and complement:
i=i||0;i-- // before
i=~-i // after
Check if variables have the same sign
// Longhand
Math.sign(x) == Math.sign(y);
// Shorthand
(x ^ y) >= 0;
Use ^ to check if numbers are not equal
if(a!=123) // beforeif(a^123) // after
Use number base for character to number conversion
parseInt(n, 36) is not only a very small character to number conversion, it also has the added value of
being case-insensitive, which may save a .toLowerCase(), like in subzey’s parseRoman function.
Use current date to generate random integers
As seen in aemkei’s Tetris game.
If you need a random boolean (0 or 1):
new Date&1 // Equivalent to Math.random()<0.5
If you need a random integer 0 <= n < 1337:
new Date%1337 // Equivalent to Math.floor(Math.random()*1337))
i=0|Math.random()*100 // before
i=new Date%100 // after
This works because a Date is stored internally in JavaScript as the amount of milliseconds since an
epoch, so the new Date is being coerced into 123somebignumber456 when you try to do integer
math on it. Of course, these “random” numbers really won’t be as random, especially if you call
them multiple times in quick succession, so keep that in mind.
Note: Do not use in fast loops, because the milliseconds might not change!
Strings
Prefer slice over substr over substring
Prefer slice(start,stop) over substr(start,length) over substring(start,stop). Omit the second parameter
to fetch everything to the end of the string. Do not use negative positions. It may be shorter
(e.g., s.substr(-n) fetches the last n characters) but does not work in Internet Explorer (including
version 9).
Split using ` “ `
Use s.split to create a character array from a string.
var chars = 'loremipsum'.split``;
Split using spread Operator
You can use the spread operator on strings to split them.
let string = "string"
string.split("") // before
[...string] // after
Split using 0
Save two bytes by using a number as a delimiter in a string to be split.
"alpha,bravo,charlie".split(",") // before
"alpha0bravo0charlie".split(0) // after
Use the little-known .link method
Strings have a built-in .link method that creates an HTML link.
html="<a href='"+url+"'>"+text+"</a>" // before
html=text.link(url) // after
Strings also have several other methods related to HTML, as documented here.
Use .search instead of .indexOf
First, because this RegExp implicit is 1 byte shorter, but you get the added value of coercion of
undefined to /undefined/ instead of ‘’ being matched at position zero.
Warning: This will fail when you search with an invalid regular expression. For
example, '.' as /./ matches any character, '+' as /+/ gives an error, so you’d want to ensure you know
what the value is.
Use .replace or .exec for powerful string iteration
Since the .replace method can take a function as its second argument, it can handle a lot of iteration
bookkeeping for you.
Use Array to repeat a string
for(a="",i=32;i--;)a+=0 // before
a=Array(33).join(0) // after
CharAt Shorthand
You can use the eval() function to do this, but this bracket notation shorthand technique is much
cleaner than an evaluation, and you will win the praise of colleagues who once scoffed at your
amateur coding abilities!
// Longhand
'myString'.charAt(0);
// Shorthand
'myString'[0]; // returns 'm'
```javascript
"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
Conditionals
If true … else Shorthand
This is a great code saver for when you want to do something if the test is true, else do something
else by using the ternary operator.
// Longhandvar big;
if (x > 10) {
big = true;
} else {
big = false;
}
// Shorthandvar big = (x > 10) ? true : false;
If you rely on some of the weak typing characteristics of JavaScript, this can also achieve more concise
code. For example, you could reduce the preceding code fragment to this:
var big = (x > 10);
//further nested examplesvar x = 3,
big = (x > 10) ? 'greater 10' : (x < 5) ? 'less 5' : 'between 5 and 10';
if (a !== true) {
// do something...
}
// Shorthandvar a;
if (!a) {
// do something...
}
Short IF’z
If you have mutiple IF variable value comparisons you can simply ass them to an array and check for
presence. You could use $.inArray as an alternative.
// Longhandif(myvar == 1 || myvar == 5 || myvar == 7 || myvar == 22) {
console.log('ya');
}
// Shorthand
([1,5,7,22].indexOf(myvar) !=- 1) && alert('yeah baby!');
Avoid braces by using commas
Shorter sentence when using commas (1 char saved).
if (i<10) {m+=5;n-=3} // beforeif (i<10) m+=5,n-=3; // after
Lookup Tables Shorthand
If you have code that behaves differently based on the value of a property, it can often result in
conditional statements with multiple elseifs or switch cases. You may prefer to use a lookup table if
there are more than two options (even a switch statement looks ugly!).
// Longhandif (type === 'aligator') {
aligatorBehavior();
}else if (type === 'parrot') {
parrotBehavior();
}else if (type === 'dolphin') {
dolphinBehavior();
}else if (type === 'bulldog') {
bulldogBehavior();
} else {
throw new Error('Invalid animal ' + type);
}
// Shorthandvar types = {
aligator: aligatorBehavior,
parrot: parrotBehavior,
dolphin: dolphinBehavior,
bulldog: bulldogBehavior
};
var func = types[type];
(!func) && throw new Error('Invalid animal ' + type); func();
Comparison Returns
We’re no longer relying on the less reliable == as !(ret == undefined) could be rewritten as !(ret) to
take advantage of the fact that in an or expression, ret (if undefined or false) will skip to the next
condition and use it instead. This allows us to trim down our 5 lines of code into fewer characters, and
it’s once again, a lot more readable.
// Longhandif (!(ret == undefined)) {
return ret;
} else{
return fum('g2g');
}
// Shorthandreturn ret || fum('g2g');
Use && and || where possible
These operators reduce the script size rather than using if statements like the ones in the examples
below.
if(a)if(b)return c // beforereturn a&&b&&c // after
if(!a)a=Infinity // before
a=a||Infinity // after
if (p) p=q; // before
p=p&&q; // after
if (!p) p=q; // before
p=p||q; // after
Switch Nightmare
Everyone loves switch statements, *cough*. Here is how you might avoid switch case syndrome.
// Longhandswitch (something) {
case 1:
doX();
break;
case 2:
doY();
break;
case 3:
doN();
break;
// And so on...
}
// Shorthandvar cases = {
1: doX,
2: doY,
3: doN
};
String x.big
Number x.toFixed
Function x.call
textNode x.data
This technique is even faster than string comparison!
Warning: This will lead to wrong results if properties or methods with those names were added.
Arrays
Using the Spread operator
Instead of passing each item of the array to a function, you can use the spread operator to pass the
entire array, as different parameters.
let array = [1,2,3];
someFunc(...array) // after
Test array length
if(array.length>1) // beforeif(array[1]) // after
Use elision
Array elision can be used in some cases to save bytes.
[undefined,undefined,2] // before
[,,2] // after
// Note: Be mindful of elided elements at the end of the element list
[2,undefined,undefined] // before length is 3
[2,,] // after length is 2
You may notice that the undefined turns empty. In fact, when we coerce an array into a string,
the undefined turns to empty string.
b="";b+=x // before
b=[b]+x // after// Bonus: b=x+[b] uses same bytes as b=[b]+x, while b="";b=x+b uses one more byte
over b="";b+=x.
Another exploitation is also useful:
((b=[1,2][a])?b:'') // before
[[1,2][a]] // after
Use coercion to do .join(',')
You can use ''+array instead of array.join(',') since the default separator of arrays is “,”.
Warning: this will only work if the contents of the Array are true-ish (except false) and consist of
Strings (will not be quoted!), Numbers or Booleans, Objects and Arrays within arrays may lead to
unwanted results:
''+[1,true,false,{x:1},0,'',2,['test',2]]// "1,true,false,[object Object],0,,2,test,2"
String coercion with array literal []
''+1e3+3e7 // before
[1e3]+3e7 // after
Use coercion to build strings with commas in them
"rgb("+(x+8)+","+(y-20)+","+z+")"; // before
"rgb("+[x+8,y-20,z]+")"; // after
Or if the first or last values are static:
"rgb(255,"+(y-20)+",0)"; // before
"rgb(255,"+[y-20,"0)"]; // after
Use Arrays as Objects
When you need to return an Object, re-use an already declared Array to store properties. An Array is
of type ‘object’, after all. Make sure the field names don’t collide with any of Array’s intrinsic
properties.
Test if Array has Several Elements
You can write if(array[1]) instead of if(array.length > 1).
Warning: This doesn’t work when the item array[1] is falsy! So only use it when you can be sure that
it’s not. You can use if(1 in array) in that case.
Object Array Notation Shorthand
Useful way of declaring small arrays on one line.
// Longhandvar a = new Array();
a[0] = 'myString1';
a[1] = 'myString2';
a[2] = 'myString3';
// Shorthandvar a = ['myString1', 'myString2', 'myString3'];
Associative Array Notation Shorthand
The old school way of setting up an array was to create a named array and then add each named
element one by one. A quicker and more readable way is to add the elements at the same time using
the object literal notation. Please note that Associative Array are essentially JavaScript Objects with
properties.
// Longhandvar skillSet = new Array();
skillSet['Document language'] = 'HTML5';
skillSet['Styling language'] = 'CSS3';
skillSet['Javascript library'] = 'jQuery';
skillSet['Other'] = 'Usability and accessibility';
// Shorthand// Don’t forget to omit the final comma otherwise certain// browsers will complain
(not naming any names, IE).var skillSet = {
'Document language': 'HTML5',
'Styling language': 'CSS3',
'Javascript library': 'jQuery',
'Other': 'Usability and accessibility'
};
Regular Expressions
RegExp Object Shorthand
Example to avoid using the RegExp object.
// Longhandvar regex = new RegExp('\d+(.)+\d+','igm'),
result = regex.exec('padding 01234 text text 56789 padding');
f='longFunctionName'
a[f](b)
a[f](c)//34
This is especially effective with functions like document.getElementById which can be reduced
to d[e]().
Note: For a single call, the relative cost is 8 + name.length characters. Each subsequent call has a
relative cost of 2 characters. For standard invocation, all calls cost name.length characters. Use this
method if 8 + name.length + (2 * invocations) < invocations * name.length
i = invocations len = minimum function length to get advantage
i | len=======
1| ∞
2 | 12
3| 7
4| 6
5| 5
6| 4
Shorten repetitive function calls
Saves a lot of chars when the script contains many function calls. 20 chars shorter in the second
example.
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
Short Function Calling
Just like #1 you can use ternary operators to make function calling shorthand based on a conditional.
// Longhandfunction x () {
console.log('x');
};
function y () {
console.log('y');
};
var z = 3;if (z == 3) {
x();
} else {
y();
}
// Shorthand
(z == 3 ? x:y)();
Shorten function names
Assign prototype functions to short variables. This may also be faster in more complex cases.
a=Math.random(),b=Math.random() // before
r=Math.random;a=r(),b=r() // after
Use named functions for recursion
Recursion is often more terse than looping, because it offloads bookkeeping to the stack.
Use named functions for saving state
If state needs to be saved between function calls, name the function and use it as a container.
function(i){return function(){console.log("called "+(++i)+" times")}}(0) // before
(function a(){console.log("called "+(a.i=-~a.i)+" times")}) // after
0,function a(){console.log("called "+(a.i=-~a.i)+" times")} // another alternative
Omit () on new calls w/o arguments
new Object is equivalent to new Object()
now = +new Date() // before
now = +new Date // after
// or
now = Date.now()
Omit the new keyword when possible
Some constructors don’t actually require the new keyword.
r=new RegExp(".",g) // before
r=RegExp(".",g) // after