135
\$\begingroup\$

What general tips do you have for golfing in JavaScript? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to JavaScript (e.g. "remove comments" is not an answer).

Note: Also see Tips for Golfing in ECMAScript 6 and above

\$\endgroup\$
  • \$\begingroup\$ I was actually wondering, is it allowed to put variables in global (saves var)? And should JavaScript golf code be a function or output something directly? I honestly think this can make much difference. \$\endgroup\$ – pimvdb May 27 '11 at 5:28
  • 1
    \$\begingroup\$ @primvdb: It is allowed, but you have to be careful because it can cause side-effects if a function is called multiple times and it is manipulating global variables, or if it is a recursive function. \$\endgroup\$ – mellamokb May 27 '11 at 13:44
  • \$\begingroup\$ This link has a bunch of tips relevant here. \$\endgroup\$ – Isiah Meadows Feb 12 '15 at 4:53

78 Answers 78

8
\$\begingroup\$

Transforming to a Boolean:

if(b){b=true}else{b=false}
b=b?true:false;
b=b?!0:!1;
b=!!b;

Note: This changes 0, "",false, null, undefined and NaN to false (everything else to true)

\$\endgroup\$
8
\$\begingroup\$

2 to a power

If for some reason you need to calculate 2 to the nth power,

1<<n is shorter than Math.pow(2,n).

If you needed to calculate 2 to the n+1th power,

2<<n is even shorter than 1<<n+1

Likewise for 4<<n for n+2, 8<<n for n+3, 16<<n for n+4, etc.


(sorry if this is too obvious)

\$\endgroup\$
  • 1
    \$\begingroup\$ and 2**nin ES6 \$\endgroup\$ – Cétia Jun 27 '18 at 7:57
  • \$\begingroup\$ @Cétia That’s ES7. \$\endgroup\$ – Sebastian Simon Jan 16 at 22:13
8
\$\begingroup\$

Free commas!

Often you'll want to include a comma in a string, perhaps like so:

f=(x,y,z)=>x+","+y+z

By abusing the string representation of arrays, this can be shortened by two bytes:

f=(x,y,z)=>[x,y]+z

This particular instance only works if you have three variables you want to concatenate as shown. You can use the same trick with two, but you need to be careful. There are three variants you might try:

f=(x,y)=>[x,y]
f=(x,y)=>[x,]+y
f=(x,y)=>x+[,y]

The first one will return an actual array rather than a string, which defeats the purpose. The second one looks like it will work, but in fact most modern browsers will remove the trailing comma when parsing the array. The third one will work though, at the same byte count as the second.


To put this to good use, say you have a function which creates the range [0...n]:

f=x=>x?[...f(x-1),x]:[0]

If returning a string with a separator is allowed, you might do something like this, saving a few bytes:

f=x=>x?f(x-1)+" "+x:0

However, you can save another byte with an array literal:

f=x=>x?f(x-1)+[,x]:0

Note that depending on how you arrange the recursion, you may end up with a leading or trailing separator, so you'll need to make sure your output format is allowed by the challenge.

Example usage

\$\endgroup\$
  • \$\begingroup\$ You may not be able to do [x,]+y, but you can do [x,,]+y. Though it occurs to me that's the same amount of bytes as x+','+y, so nevermind. \$\endgroup\$ – Patrick Roberts Oct 5 '17 at 5:43
7
\$\begingroup\$

for a given array, we know a for..in loop might lead to errors because stuff might be added to the Array.Prototype, so we revert to a normal for loop:

So instead of this iteration:

for (var i=0; i<arr.length; i++ )

lets do this:

for (var i=arr.length; i--; )

if we just want to iterate the Array not caring it goes backwards

\$\endgroup\$
  • 1
    \$\begingroup\$ Nicely found, but var can be dropped here as well I guess. Secondly, I honestly don't think you'd add functions to Array.prototype when golfing. \$\endgroup\$ – pimvdb Jun 7 '11 at 20:12
  • \$\begingroup\$ var makes the counter a local and not global variable, and globals are considered bad \$\endgroup\$ – vsync Jun 7 '11 at 21:17
  • 11
    \$\begingroup\$ Indeed globals are considered bad in general JavaScript programming. But in code-golfing, it saves 4 characters which is never bad :-) In code golfing, you're generally breaking a lot of readability and usability rules anyway to squeeze out the last character. \$\endgroup\$ – mellamokb Jun 8 '11 at 11:53
  • 12
    \$\begingroup\$ @vsync: It seems like you're missing the point of golfing. Golf code isn't supposed to be readable, flexible, reliable or even maintainable. It's not for practical application, but just for fun challenges. Coding standards don't matter at all - all that matters is making your code short. \$\endgroup\$ – kba Nov 29 '11 at 6:07
  • 1
    \$\begingroup\$ Actually, reversing for loops saves 1 character, more in a few cases. \$\endgroup\$ – Isiah Meadows Dec 3 '14 at 22:25
7
\$\begingroup\$

Repeated characters

Be creative when trying to repeat the same character:

"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
s="a";while(s.length<32)s+=s
for(s="a";s.length<32;s+=s)
for(s="aa",i=4;i--;s+=s)
s="aaaaaaaa",s+=s,s+=s
s="aaaaaaaa",s+=s+s+s
Array(33).join("a")

With ES6, this becomes even shorter:

'a'.repeat(32)

Note: It is unlikely that you use it to form a string, but the idea can be applied to form large numbers too

\$\endgroup\$
  • 8
    \$\begingroup\$ new could be dropped; the Array constructor called as a function does the same as if it's called as a constructor. If the character to repeat is unimportant, it could be left out and it'll default to ",". \$\endgroup\$ – FireFly Aug 30 '12 at 21:59
7
\$\begingroup\$

Conditionally reverse an array with .sort

Let's say you have an array, l, and you want to reverse it if and only if someBoolean.

The naïve way to do it would be if(someBoolean)l.reverse()

Instead, you can abuse the way that JavaScript's sort function works.

if(someBoolean)l.reverse() // before
someBoolean&&l.reverse()   // golfier before
l.sort(_=>someBoolean)     // after
                      ^^^^
\$\endgroup\$
  • \$\begingroup\$ Note that the last line l.sort(_=>someConstant) is implementation dependent. It works on Firefox, but not on V8 where this fails when there's >10 elements, or there's undefined values inside the array. \$\endgroup\$ – Voile Dec 20 '17 at 2:46
7
\$\begingroup\$

Converting a number from hexadecimal

Instead of using the lengthy parseInt to convert a number from hexadecimal:

parseInt(a,16)

Add "0x" to the beginning, then convert to a number with a usual technique:

+("0x"+a)   // 5 bytes saved

Even better solution, abusing order of operations:

"0x"+a-0    // another byte saved

Note that this last one will not work in all situations, depending on the surrounding operators.

In ES6, you can also use this trick to convert from octal or binary:

"0b"+a-0   // binary
"0o"+a-0   // octal
\$\endgroup\$
  • 2
    \$\begingroup\$ An additional alternative is 0|"0x"+a \$\endgroup\$ – Tomas Langkaas Sep 8 '17 at 17:09
6
\$\begingroup\$

Sometimes declaring a variable (or more) as function parameters can save some strokes by avoiding the var keyword. This use case is fairly rare though:

function f(){var i} => function f(i){}

Also you can use short circuit operators to avoid if statements:

if(a)b => a&&b

if(!a)b => a||b

To coerce to a number: str-0

\$\endgroup\$
6
\$\begingroup\$

Use valueOf to make shorter function calls. Instead of:

function f(){...}
f()

use

f={valueOf:function(){...}}
+f

If you call the function f frequently enough, you will save characters because +f is 1 shorter than f().

If you usef even more than that, you can use __defineGetter__:

__defineGetter__('f',function(){...})
f

This trick also works for a function that takes 1 argument.

function f(v){...}
f(x)

Becomes

__defineSetter__('f',function(v){...})
f=x

But now it will always return v.


Edit: I forgot to mention this, but it only works for a function that doesn't take arguments.

\$\endgroup\$
  • \$\begingroup\$ The var keyword is unnecessary. Same with the semicolons. n={valueOf:f} would be enough for that line. \$\endgroup\$ – mbomb007 May 21 '15 at 19:36
  • \$\begingroup\$ Duly noted; edited \$\endgroup\$ – Cyoce May 22 '15 at 19:21
  • \$\begingroup\$ I had no idea this was possible in JS! But there's a typo in your last example; it should be __defineGetter__('f',function(){}) rather than __defineGetter('f',function(){})__. \$\endgroup\$ – ETHproductions Nov 22 '16 at 15:49
  • \$\begingroup\$ @ETHproductions I guess I missed that. Fixed. \$\endgroup\$ – Cyoce Nov 22 '16 at 16:05
  • \$\begingroup\$ And it is even shorter in ES2015+: f={valueOf(){…}} or f={valueOf:_=>…}. \$\endgroup\$ – Toothbrush Jan 9 at 12:36
6
\$\begingroup\$

Comparing numbers by absolute value:

a*a<b*b // 7 bytes

Vastly shorter than Math.abs (8 bytes without counting ()), and like calling the function this will allow casting strings to numbers on the fly.

Sorting by arrays of multiple values, comparing them all one by one (e.g. finding minimum time durations in 01:23:45 notation):

a.map(v=>v.split`:`).sort(([h,m,s],[g,n,a])=>h-g||m-n||s-a)[0].join`:`

This example sorts 00:00:00 < 01:00:00 < 01:00:01 < 22:59:59 < 23:00:00 and finds the smallest element. This works because || short-circuits for any value that isn't falselike and so the expression h-g||m-n||s-a will evaluate the next value in the chain only when the last difference was 0.

\$\endgroup\$
  • 1
    \$\begingroup\$ The standard string comparing sort will do just fine with this example \$\endgroup\$ – pepkin88 Sep 26 '18 at 12:39
5
\$\begingroup\$

Initialize arrays with [] instead of Array(), and add to arrays with [.length]:

a=[];       // initialize a new array
a[0]=15;    // insert element to end of array
a[1]=30;    // insert another element to end of array
\$\endgroup\$
  • 8
    \$\begingroup\$ note: I know this is obvious, but if we are going to insert elements too close to index 0, it might be good idea to write it like this a=[15,30]; \$\endgroup\$ – ajax333221 Dec 18 '12 at 16:36
  • 7
    \$\begingroup\$ You can also leave elements undefined (say if you want a 2 indexed version of the above -> a=[,,15,30];. Also, I think you're suggesting adding things to the array using a[a.length]=x, but a.push(x) is shorter... \$\endgroup\$ – Alconja Aug 7 '14 at 1:59
  • \$\begingroup\$ Not a[a.length]. @Alconja is correct in suggesting a.push. \$\endgroup\$ – Isiah Meadows Feb 12 '15 at 4:42
  • \$\begingroup\$ a.push(4) // returns index a[a.length]=5 // returns new value a=[...a,3] // returns array [...a,3] // doesn't mutate \$\endgroup\$ – imma Jan 26 '18 at 15:24
  • \$\begingroup\$ well it seems breaks and pre markdown isn't working :-( \$\endgroup\$ – imma Jan 26 '18 at 15:26
5
\$\begingroup\$

Treat strings like you do C Strings.

Given s="hello"

s[0]

is equivalent to

s.charAt(0)

and

s.split("")[0]
\$\endgroup\$
  • 1
    \$\begingroup\$ This is EcmaScript 5, but for code golf it's fine. \$\endgroup\$ – Konrad Borowski Jan 4 '13 at 12:03
  • 1
    \$\begingroup\$ @xfix Yes, it's defined in EcmaScript 5, but Firefox has supported it from version 0.9. \$\endgroup\$ – Toothbrush Feb 24 '14 at 10:37
  • 2
    \$\begingroup\$ Too bad JS doesn't support a[3]="d". Instead we have to use the obnoxiously long a=a.slice(0,3)+"d"+a.slice(4). \$\endgroup\$ – ETHproductions Dec 22 '15 at 1:08
  • \$\begingroup\$ @ETHproductions try: a=s.split('e').join('d'); And for this case (2 L's) - s.split('ll').join('ld'); \$\endgroup\$ – yonatanmn Apr 23 '16 at 9:08
  • 1
    \$\begingroup\$ what about '12345'.replace(/(..)./,'$1d') \$\endgroup\$ – l4m2 Apr 13 '18 at 16:19
5
\$\begingroup\$

Some extra tricks that I don't see very often, that are more JS-specific:

  • Use array literals and indexing as a sort of switch as an expression. You can leave out "unnecessary" elements and they'll default to undefined (which is a falsy value, by the way). E.g. [,1,,-1][i%4] would evaluate to either 1 or -1 depending on whether i is 1,5,9,13,... or 3,7,11,15,... (and we don't care about the other cases).

  • Similarly, use object literals when you want arbitrary strings for the keys.

  • This one is common to all C-style languages: (ab)use the fact that that & and | works just as well as && and || with boolean values, albeit with different precedence. Keep in mind that the single-character variants aren't short-circuiting though!

  • -~x is the same as x+1, and ~-x is the same as x-1. Sometimes the {bitwise,arithmetic} negation variants are useful to avoid extra parens; for instance, 4*~-n rather than 4*(n-1).

  • ~9 could be used as a two-character literal for the value -10 (I've never had a use for this, but it's a fun curiosity).

\$\endgroup\$
5
\$\begingroup\$

You can use -~s instead of +s+1, and ~-s instead of +s-1, if s is a string or a number between -(2^31)-1 and 2^31.

\$\endgroup\$
  • \$\begingroup\$ Actually, it's also sometimes great for numbers if you want to not actually increment the number, where this has higher precedence than s+1 \$\endgroup\$ – Isiah Meadows Feb 11 '15 at 2:08
  • \$\begingroup\$ And multiplication. \$\endgroup\$ – Isiah Meadows Feb 11 '15 at 2:08
  • \$\begingroup\$ s-1 will also coerce s to a number. \$\endgroup\$ – Shaggy Sep 12 '18 at 11:57
  • \$\begingroup\$ @Shaggy True. So will +s, s*n, -n, s/n, n-s, etc. where n is a Number (as opposed to a String). \$\endgroup\$ – Toothbrush Sep 12 '18 at 20:53
  • \$\begingroup\$ Because ~ is a bitwise operator, it will treat NaN or undefined as 0, which may be useful in some cases. \$\endgroup\$ – user202729 Jan 9 at 4:26
5
\$\begingroup\$

When it comes to comparing strings against eachother, you’d normally use

x=='*'

If it is the case that x only has a few fixed options, e.g. x can only be one of the lowercase letters or the asterisk (*), then you can use JavaScript’s string comparison like this:

x<'a'

In the case of limited options, this will be true if and only if x=='*' and false otherwise, saving one amazing byte! This is based on the Unicode table.

For an actual example, see this revision of an answer of mine.

\$\endgroup\$
5
\$\begingroup\$

setInterval Hacks

Pass a string instead of a function to setInterval.

setInterval(function(){console.log(0)},1) //before
setInterval('console.log(0)',1) //after

You can also omit the last argument if you don't care about the speed at which your interval will execute. NOTE: This does not work in Firefox...

setInterval('console.log(0)',1) //before
setInterval('console.log(0)') //after
setInterval`console.log(0)` //after - ES6 only
\$\endgroup\$
  • \$\begingroup\$ They all work in Firefox \$\endgroup\$ – Toothbrush Nov 5 '15 at 16:42
  • \$\begingroup\$ @Toothbrush not the second tip. That only executes once before stopping. \$\endgroup\$ – Mama Fun Roll Feb 1 '16 at 17:28
  • \$\begingroup\$ You are right, but I'm sure it worked when I tried it. \$\endgroup\$ – Toothbrush Feb 10 '16 at 17:24
  • \$\begingroup\$ You can pass additional arguments to setInterval which will be passed to the function argument when it is called. For example setInterval("f(x,y)",1e3) becomes setInterval(f,1e3,x,y) for a 3 byte saving. \$\endgroup\$ – Shaggy Sep 12 '18 at 12:03
5
\$\begingroup\$

document.getElementById

This one's a HUGE byte-saver.

document.getElementById('a').innerHTML="foo"; //before
a.innerHTML="foo"; //after
\$\endgroup\$
5
\$\begingroup\$

Use with to import methods and properties from objects into the local scope.

It becomes more apparent with longer class names or repeated use of the same one:

a=Math.max(1,2),b=Math.min(2,7),c=Math.sqrt(100)
with(Math)a=max(1,2),b=min(2,7),c=sqrt(100)
\$\endgroup\$
  • 1
    \$\begingroup\$ Note: you don't need to initialize your variables while golfing. let a,b,c; would be unnecessary. \$\endgroup\$ – Cyoce May 18 '16 at 21:42
  • \$\begingroup\$ @Cyoce True, thanks for the tip! \$\endgroup\$ – Scott May 18 '16 at 23:59
4
\$\begingroup\$

Another thing I came across is forcing a multidimensional array into a single-dimensional array like this:

[[1,2],[3,4]].join().split(",") // ["1", "2", "3", "4"]

It does convert everything into strings, so basically only numbers/strings are possible, but it can come in handy. Calculating with strings automatically converts it into numbers anyway.

EDIT: As Austin Hyde pointed out, you can flatten one level like this:

[].concat.apply([],[[1,2],[3,4]])

Although it only takes it down one level, the data types remain.

\$\endgroup\$
  • 1
    \$\begingroup\$ yeah but if you need to use indexOf on the array later to find numbers in it...it won't find them if the array so made of strings, so this is more pure flattening \$\endgroup\$ – vsync Jun 7 '11 at 20:05
  • 2
    \$\begingroup\$ [].concat.apply([],[[1,2],[3,4]]) also works, but only flattens it one level. It's two characters longer, but works on any data type. \$\endgroup\$ – Austin Hyde Jun 13 '11 at 18:11
  • 1
    \$\begingroup\$ Unless you just need to pass in an array, you can flatten it like this: [].concat([1,2],[3,4]), and if you need to pass in an array and you know the contents, this works too: [].concat(a[0],a[1]). \$\endgroup\$ – Camilo Martin Dec 18 '12 at 12:09
  • 3
    \$\begingroup\$ If you want to use ES6, you can use the spread operator and shorten that example to [...[1,2],...[3,4]] \$\endgroup\$ – Alconja Aug 7 '14 at 2:08
  • 1
    \$\begingroup\$ You could also abuse implicit type casting to save a few bytes: ([[1,2],[3,4]]+"").split(",") \$\endgroup\$ – ETHproductions Nov 22 '16 at 17:05
4
\$\begingroup\$

There's a few other ideas that come to mind:

Ternary operators with functions

Ternary operators also work well as a substitute for if..then..else statements with functions...

if(a==b){
   c();
}else{
   if(a==d){
       e();f();
   }
   g();
}

can be replaced with

(a==b)?c():(((a==d)&&(e()|f()))|g())

You can take this further by abusing functions that don't take parameters:

a==b?c():g(a==d&&f(e()))

If a, b, and d are numbers, you can use subtraction to test for 0.

a-b?g(a-d||f(e())):c()

Decimal Base Exponents

Another is the reduction of decimal base exponents... for example 1000000 can be replaced with 1e6

\$\endgroup\$
  • \$\begingroup\$ The question asks for tips which are somewhat specific to Javascript. The ternary operator is included in the tips for all languages. \$\endgroup\$ – Peter Taylor Mar 17 '14 at 20:36
  • 1
    \$\begingroup\$ Yes, but not all languages have the ternary operator, Pete... Besides, I put this in some six months ago... \$\endgroup\$ – WallyWest Mar 17 '14 at 22:45
  • \$\begingroup\$ Enough languages have it: there's no point mentioning it on lots of separate per-language tips pages. It's been on the generic tips for some 11.5 months; I've commented on it today because I commented on it in a new language tips page and the person who'd posted it there mentioned that lots of other ones had it. \$\endgroup\$ – Peter Taylor Mar 17 '14 at 23:02
  • \$\begingroup\$ @PeterTaylor Sure, a lot of languages have a ternary operator... But how many have ternaries for top-level expressions or functions that return void? JS is nearly on a class of its own in that respect. \$\endgroup\$ – Mario Carneiro Jan 30 '16 at 18:36
4
\$\begingroup\$

Prefer Array#map() to Array#forEach()

Self-explanatory, a flat 4 bytes saved

a.forEach(function(e){/* ... */})
a.map(function(e){/* ... */})
\$\endgroup\$
4
\$\begingroup\$

Determining if an array is empty

The empty array is truthy in JavaScript, i.e. []?b:c returns b. This leaves us to find our own ways to determine if an array is empty. The most obvious way is .length:

a.length?b:c

However, this can be shortened by 2 bytes with the in operator:

0 in a?b:c

Note: unlike in Python, x in y checks whether y has a key x; it's a shorthand for y.hasOwnProperty(x).

This is, I believe, the shortest code that unconditionally detects whether a is empty. However, there are a few alternatives that work in various scenarios:

a[0]?b:c

This works iff the first item in a is guaranteed to be truthy. For example, a=[1];a[0] returns 1, which is truthy; a=[];a[0] returns undefined, which is falsy; but a=[0];a[0] returns 0, which is also falsy. But in general, this trick works on arrays of chars or positive numbers.

a+""?b:c

When arrays are casted to strings, the brackets are left out. [1,2,3]+"" returns the string "1,2,3". So casting a to a string will return the empty string (falsy) for the empty array, and a truthy string otherwise.

Caveat: If a contains a single array which contains either nothing or a single array containing... etc., e.g. [[]], [[[[[[]]]]]], it will still be casted to the empty string.

a+a?b:c

This is practically exactly the same as the above example, but a byte shorter. When + is called on two arrays, JS stupidly converts them both to strings and concatenates those. So a+a returns exactly the same thing as a+"", but doubled.

\$\endgroup\$
  • 1
    \$\begingroup\$ Note that 0 in a and a[0] will fail for sparse arrays such as a = [,1,2]. Thus, !a.length is the most safe way to test for an empty array. When taking advantage of type casting to string, a==0 is another solution that directly returns a boolean value. \$\endgroup\$ – Tomas Langkaas Sep 8 '17 at 16:06
4
\$\begingroup\$

Instead of checking if something is a string like this:

var a = "aString";
if (typeof a === 'string') {
    runSomething();
}

You can do this:

var a = "aString";
a===''+a&&runSomething();
\$\endgroup\$
  • \$\begingroup\$ Nice! Can also be used for checking other types, such as numbers, n===+n, and booleans, b===!!b. \$\endgroup\$ – Tomas Langkaas Sep 8 '17 at 16:57
3
\$\begingroup\$

Less/Greater than "10/100/1000..." vs "9/99/999...":

//for(i=0;i<20;i++){
    if(i<10){}else{}
    if(i>9){}else{}
//}

Note: Just remember to swap what is inside the if with the else

\$\endgroup\$
3
\$\begingroup\$

For strings and arrays, instead of using a=b.length>a.length?b:a to set a to b if b.length > a.length, you can use a=b[a.length]?b:a.

Note: If b is an array and contains either 0 or false, you'll have to use a=b[a.length]!=null?b:a (still one character shorter).

\$\endgroup\$
3
\$\begingroup\$

Return 1 for true, 0 for false as much as possible

This should be relatively self-explanatory.

function f(x){return x?(d(x),!1):!0}
function f(x){return x?(d(x),0):1}
function f(x){return !x&&d(x)&0}
if(f(v)){/* ... */}

// ES6 versions
let f=x=>x?(d(x),!1):!0
let f=x=>x?(d(x),0):1
let f=x=>!x&&d(x)&0
if(f(v)){/* ... */}
\$\endgroup\$
  • \$\begingroup\$ Don't get what's going on here but from your description +!!x is shorter and more concise. \$\endgroup\$ – George Reith Nov 5 '15 at 17:27
3
\$\begingroup\$

If returning void, see if it is shorter to return something useful. This is kinda language-agnostic here.

This isn't an easy apply-anywhere thing, either, though. Word of warning, make sure your parentheses are balanced.

In ES6, in this example, 6 bytes saved

let l=x=>console.log(m+x),x=1,a;l(a=f(x));l(a=g(a));l(h(a))
let l=x=>(console.log(m+x),x),x=1;l(h(l(g(l(f(x))))))

In ES5, it is only 1 byte saved

function l(x){console.log(m+x)}var x=1,a;l(a=f(x));l(a=g(a));l(h(a))
function l(x){console.log(m+x);return x}var x=1;l(h(l(g(l(f(x))))))
\$\endgroup\$
  • \$\begingroup\$ If you need to call a void-returning function repeatedly, it can be especially useful to return the function itself. For example, l=(x,y)=>c.lineTo(x,y);l(1,2);l(3,4);l(5,6);l(7,8) can be rephrased as l=(x,y)=>c.lineTo(x,y)||l;l(1,2)(3,4)(5,6)(7,8), saving 3 bytes. Example usage \$\endgroup\$ – ETHproductions Nov 22 '16 at 16:56
3
\$\begingroup\$

Use shorthands instead of primitives

Most of these are done by any sane minifier, but not all.

  • 2 bytes saved

    true
    !0
    
  • 3 bytes saved

    false
    !1
    
  • 3 bytes saved

    Infinity
    9e999
    
  • 4 bytes saved

    undefined
    [][0]   (any digit works)
    
\$\endgroup\$
  • \$\begingroup\$ Undefined is [][0] \$\endgroup\$ – edc65 Feb 11 '15 at 0:14
  • \$\begingroup\$ @edc65 Thanks! Fixed. \$\endgroup\$ – Isiah Meadows Feb 11 '15 at 1:50
  • 7
    \$\begingroup\$ 1/0 => Infinity \$\endgroup\$ – squeamish ossifrage Oct 13 '15 at 8:47
  • 2
    \$\begingroup\$ undefined is also probably [].a \$\endgroup\$ – muhmuhten Nov 6 '15 at 5:21
  • 1
    \$\begingroup\$ Or, if x is a variable that does not hold null or undefined, you can do x.a for undefined. \$\endgroup\$ – Cyoce May 24 '16 at 18:08
3
\$\begingroup\$

Abuse uninitialized variables, mostly for null and undefined

  • undefined varies, some better than others

    • One-time use (5 bytes saved):

      undefined
      1..a       (any digit+letter works)
      
    • Multiple uses (8 per use - 5 bytes saved, 10 bytes for 2 uses)

      undefined;undefined
      var u;u;u
      
    • Existing declaration (8 per use - 5 bytes saved, 5 bytes for 1 use, 13 bytes for 2 uses)

      var x;undefined
      var x,u;u
      
      var x;undefined;undefined
      var x,u;u;u
      
  • null varies, generally better replaced in larger golfs

    • If there is a declaration anywhere, replace it unless null is specifically required (3 per use - 2 bytes saved).

      var x;null
      var x,n;n
      
    • Single uses:

      • If no variable declaration exists, do not change.

      • If any undefined exists (in any form), declare an unused variable (5 bytes saved if one of each).

        v==null;undefined
        var u;v==u;u
        
      • If more than two such tests exist, declare an unused variable (two are equal).

        a==null;b==null;c==null
        var u;a==u;b==u;c==u
        
      • Otherwise, keep as null

    • Multiple uses:

      • Declare an unused variable, unless null is specifically required (2 is equivalent).

        null;null;null
        var u;u;u;u
        
  • Prefer to avoid these tests when possible. Aim for implicit boolean tests (if(0);)

\$\endgroup\$
  • \$\begingroup\$ Another way to get undefined easily is 1..a \$\endgroup\$ – Dom Hastings May 19 '16 at 12:05
  • \$\begingroup\$ Good catch - I fixed it \$\endgroup\$ – Isiah Meadows May 19 '16 at 23:37
  • \$\begingroup\$ If you're restricted to non-alphanumeric characters, [].$ will also equal undefined \$\endgroup\$ – WallyWest Sep 12 '18 at 23:11
2
\$\begingroup\$

Convert ints to strings by adding an empty string

For example:

39323+""

Returns:

"39323"

Update:

Adding [] works too

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.