173
\$\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\$
4
  • \$\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, 2011 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, 2011 at 13:44
  • \$\begingroup\$ This link has a bunch of tips relevant here. \$\endgroup\$
    – Claudia
    Feb 12, 2015 at 4:53
  • 1
    \$\begingroup\$ I have discovered probably the most useless tip: a private class element doesn’t require a space before the private identifier in cases where it is preceded by a keyword: (class{static #x = 1;get #y(){};set #y(z){}}) can be rewritten as (class{static#x = 1;get#y(){};set#y(z){}}). This makes for some nice obfuscation, too, but I can’t think of a practical example in code golf. \$\endgroup\$ Nov 1, 2021 at 15:26

97 Answers 97

1 2 3
4
1
\$\begingroup\$

For ES6 arrow functions with 2 parameters, nest functions

f=(x,k)=>x+k
f=x=>k=>x+k

Only works in some cases. E.g. for recursive functions, this doesn't help because calling is one byte longer:

f(1,2)
f(1)(2)
\$\endgroup\$
0
\$\begingroup\$

I have adapted to my needs the Unicode shortcuts method by @bebe.

The problem which many have faced with the original solution is due to the fact that some of the functions/properties belong to a class prototype while others to a class itself. These need to be handled separately.

The minified code now takes 132 bytes:

[Number,S=String,Array].map(r=>{f=(r=>Object.getOwnPropertyNames(r).map((e,t)=>r[S.fromCharCode(t+248)]=r[e])),f(r),f(r.prototype)})

Of course, you can drop Number and Array if unused from the initial array to save a couple of bytes. String is used in the code itself so removing it doesn't help a lot.

Part of the problems came from Math having no protype thus requiring its special handling. Besides the name in the initial array it also takes another 5 bytes to skip prototype handing. So use the variant below only if you need Math:

[Number,S=String,Array,Math].map(r=>{f=(r=>Object.getOwnPropertyNames(r).map((e,t)=>r[S.fromCharCode(t+248)]=r[e])),f(r),r.E||f(r.prototype)})

I use the same code for Node.js (v12.19.0) and Chrome (90.0.4430.212 x64).

Code Char Number          Number.prototype String        String.prototype  Array    Array.prototype Math
248  ø    length            constructor    length        length            length    length         abs
249  ù    name              toExponential  name          constructor       name      constructor    acos
250  ú    prototype         toFixed        prototype     anchor            prototype concat         acosh
251  û    isFinite          toPrecision    fromCharCode  big               isArray   copyWithin     asin
252  ü    isInteger         toString       fromCodePoint blink             from      fill           asinh
253  ý    isNaN             valueOf        raw           bold              of        find           atan
254  þ    isSafeInteger     toLocaleString               charAt                      findIndex      atanh
255  ÿ    parseFloat                                     charCodeAt                  lastIndexOf    atan2
256  Ā    parseInt                                       codePointAt                 pop            ceil
257  ā    MAX_VALUE                                      concat                      push           cbrt
258  Ă    MIN_VALUE                                      endsWith                    reverse        expm1
259  ă    NaN                                            fontcolor                   shift          clz32
260  Ą    NEGATIVE_INFINITY                              fontsize                    unshift        cos
261  ą    POSITIVE_INFINITY                              fixed                       slice          cosh
262  Ć    MAX_SAFE_INTEGER                               includes                    sort           exp
263  ć    MIN_SAFE_INTEGER                               indexOf                     splice         floor
264  Ĉ    EPSILON                                        italics                     includes       fround
265  ĉ                                                   lastIndexOf                 indexOf        hypot
266  Ċ                                                   link                        join           imul
267  ċ                                                   localeCompare               keys           log
268  Č                                                   match                       entries        log1p
269  č                                                   matchAll                    values         log2
270  Ď                                                   normalize                   forEach        log10
271  ď                                                   padEnd                      filter         max
272  Đ                                                   padStart                    flat           min
273  đ                                                   repeat                      flatMap        pow
274  Ē                                                   replace                     map            random
275  ē                                                   search                      every          round
276  Ĕ                                                   slice                       some           sign
277  ĕ                                                   small                       reduce         sin
278  Ė                                                   split                       reduceRight    sinh
279  ė                                                   strike                      toLocaleString sqrt
280  Ę                                                   sub                         toString       tan
281  ę                                                   substr                                     tanh
282  Ě                                                   substring                                  trunc
283  ě                                                   sup                                        E
284  Ĝ                                                   startsWith                                 LN10
285  ĝ                                                   toString                                   LN2
286  Ğ                                                   trim                                       LOG10E
287  ğ                                                   trimStart                                  LOG2E
288  Ġ                                                   trimLeft                                   PI
289  ġ                                                   trimEnd                                    SQRT1_2
290  Ģ                                                   trimRight                                  SQRT2
291  ģ                                                   toLocaleLowerCase
292  Ĥ                                                   toLocaleUpperCase
293  ĥ                                                   toLowerCase
294  Ħ                                                   toUpperCase
295  ħ                                                   valueOf
296  Ĩ                                                   replaceAll (*)

Notes:

replaceAll (marked with an asterisk) exists only for Chrome.

Some comments where criticizing the usage of non-standard alphabet. If you manage to find another consistent range of Unicode characters that can be used as property names in JS then feel free to improve this answer. I couldn't find better than the original.

\$\endgroup\$
0
\$\begingroup\$

If f returns 0 and 1, then f(0)|f(1) can be f(f(1))

\$\endgroup\$
0
\$\begingroup\$

Pass expression rather than function

g`x+y`

is shorter than

g(x=>y=>x+y)

if g is used for 2 times

eval(z,x=p+1,y=q-1)

is 9 bytes longer than

z(p+1,q-1)

and

eval(z)

is only 1 byte longer than

z(x,y)

Recent use here

\$\endgroup\$
-1
\$\begingroup\$

Add elements to Array

The concat is more useful than push in many situations because it returns whole array e.g. we want from d=[{a:1,b:2,c:3},{a:7,b:8,c:9}] generate 'pivot object' p={"a":[1,7],"b":[2,8],"c":[3,9]}

let p={}, d=[{a:1,b:2,c:3},{a:7,b:8,c:9}]; 

d.map(x=> Object.keys(x).map(k=> p[k]= (p[k]||[]).concat(x[k]) ))

console.log(JSON.stringify(p));

\$\endgroup\$
2
  • 2
    \$\begingroup\$ Instead of mapping the keys, you can do for(k in x) and, instead of the concatenation, you can do p[k]=[...p[k]||[],x[k]]. After wrapping that in {}s, it saves you 14 bytes. TIO \$\endgroup\$
    – Shaggy
    Sep 17, 2019 at 9:37
  • \$\begingroup\$ @Shaggy thanks :) - I don't know that tricks. May be you have also some suggestion to this? \$\endgroup\$ Sep 17, 2019 at 10:10
-1
\$\begingroup\$

The 9**999 is Infinity shortcut (2 characters shorter)

console.log( 9**999===Infinity )

\$\endgroup\$
2
  • 13
    \$\begingroup\$ 1/0 is a bit shorter \$\endgroup\$
    – James
    Feb 27, 2020 at 14:53
  • \$\begingroup\$ @James wow - it is not NaN (I don't know this) \$\endgroup\$ Feb 27, 2020 at 14:58
-2
\$\begingroup\$

Converting a string to an int/float by subtracting a empty array

Before(22 bytes)

parseFloat("12.52463")

After(13 bytes, saved 9 bytes)

"12.52463"-[]
\$\endgroup\$
2
  • 15
    \$\begingroup\$ This is covered by other answers already. The shortest version is +"12.52463". \$\endgroup\$ Feb 10, 2015 at 19:18
  • \$\begingroup\$ @MartinEnder What about [restricted-source] questions? Maybe sometimes you can't use +. \$\endgroup\$
    – VFDan
    May 19, 2020 at 19:25
1 2 3
4

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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