3
\$\begingroup\$

Are there any tricks to shorten defined function names like setInterval, onkeydown, onkeyup, createLinearGradient or even return?

When using it more than once it's nice to put it as a string into a variable and reuse it afterwards but most functions I only need once.

I know that ES6 has arrowed functions - maybe there is an apporach?

\$\endgroup\$
2
  • 5
    \$\begingroup\$ FYI: return is not a function. \$\endgroup\$
    – Ingo Bürk
    Oct 21, 2014 at 14:33
  • 1
    \$\begingroup\$ I'm aware of that - I acutally meant "long" strings in general :) \$\endgroup\$ Oct 21, 2014 at 16:05

3 Answers 3

7
\$\begingroup\$

There is a rather clever trick for shortening method names for a particular object that I first learned about during the first JS1k competition. See Martijn Haverbeke's page about it, under "Mechanized Abbreviation".

The idea is that you iterate over the keys of the object and apply a hash function h(k) to each of the keys in order to compute an alias for the key. With some trickery you can make sure to only apply the aliasing to keys referring to function values (i.e. only if typeof o[k] == 'function'), but of course this costs some extra characters. If only one of the keys being aliased hash to the same value, then you can use the abbreviated name unambiguously. If there are collisions you have to fall back to the full name (since the order of iteration is undefined).

When using this trick, remember that it's a trade-off between length of hash function (expression) and number of collisions. Of course, this approach is only helpful when you use a lot of long-name methods on one particular object (e.g. canvas code). For a paricular snippet that you want to golf, it could be useful to find the number of occurrences of each identifier and put together something like this page, to simplify the search for a good hash function.

This trick could be used with global functions since the global object is this at the global scope (or even shorter, windows = window.top = top in a web environment). Also, another thing to keep in mind with frequent use of methods on one object is the with statement.

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

There are a lot of different cases here. I'll try to address as many as I can think of, but others might spot a few additional ones.

For starts, return is not a function. It's a keyword. So you're out of luck there. (Unless you can write your function in a single statement, in which case ES6 arrow functions make the return implicit, like f=s=>s.length instead of f=s=>{return s.length;}.)

For static-like functions such as setInterval or Math.sin you can just give them a new name:

t=setInterval
s=Math.sin

If you want to call a function on an object repeatedly, you'll have to work a bit harder though. For instance if you want to use s.charCodeAt multiple times on a string s, then you cannot do:

c=s.charCodeAt
c(1)
c(2)
...

Because if invoked like this, c will not know it's this-context. The simplest option here is to store c as a property of s:

s.c=s.charCodeAt
s.c(1)
s.c(2)

If you're using this very often though, you don't want to write the s. every time. To get rid of that, you'll need to write your own function. Using ES6 notation:

c=i=>s.charCodeAt(i)
c(1)
c(2)

Note however that this requires that you always want to call it on the same s. However, if you want to use a shortened member function on several objects, you can make those parameters:

c=(o,i)=>o.charCodeAt(i)
c(s,1)
c(t,2)
...

Then there's also the option to modify the prototype to patch the function into every instance of a class, but I'd have to look up the details.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ Alternatively, you could cache the property name: s[c='charCodeAt'](1) s[c](2) \$\endgroup\$
    – nderscore
    Oct 22, 2014 at 19:44
  • \$\begingroup\$ c="".charCodeAt.call ... OK, it's not very short, but at least I tried. \$\endgroup\$ Jan 12, 2015 at 13:17
  • \$\begingroup\$ Note: comma operator can be used to squash some things into a single statement. \$\endgroup\$
    – gcampbell
    Jun 10, 2016 at 10:44
2
\$\begingroup\$

ES6 can be the answer regarding function definition, with arrow functions, array comprehension and closure expressions

ECMAScript 5:

function z(a) {
  statement; statement; ...
  return value;
}

ECMAScript 6

z=a=> {
   statement; statement; ...
   return value;
}

// or

z=a=> expression

Example Factorial

function f(n) { for(r=1;n;n--;) r*=n; return r } // Iterative

function f(n) { return n>1 ? n*f(n-1) : 1 } // recursive

f=n=> n>1 ? n*f(n-1):1// ES6 recursive
\$\endgroup\$

Your Answer

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

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