2
\$\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\$
  • 1
    \$\begingroup\$ Use jQuery library ? \$\endgroup\$ – Michael M. Oct 21 '14 at 14:21
  • 1
    \$\begingroup\$ Although tips in languages are encouraged here, this is a very particular question that might not entertain more than 1 or 2 answers. It would get better reception on SO :) \$\endgroup\$ – Optimizer Oct 21 '14 at 14:22
  • 5
    \$\begingroup\$ @Optimizer What's the significance of how many answers an advice question might get? \$\endgroup\$ – Martin Ender Oct 21 '14 at 14:29
  • 5
    \$\begingroup\$ FYI: return is not a function. \$\endgroup\$ – Ingo Bürk Oct 21 '14 at 14:33
  • 1
    \$\begingroup\$ I'm aware of that - I acutally meant "long" strings in general :) \$\endgroup\$ – misantronic Oct 21 '14 at 16:05
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\$
  • 1
    \$\begingroup\$ Alternatively, you could cache the property name: s[c='charCodeAt'](1) s[c](2) \$\endgroup\$ – nderscore Oct 22 '14 at 19:44
  • \$\begingroup\$ c="".charCodeAt.call ... OK, it's not very short, but at least I tried. \$\endgroup\$ – John Dvorak Jan 12 '15 at 13:17
  • \$\begingroup\$ Note: comma operator can be used to squash some things into a single statement. \$\endgroup\$ – gcampbell Jun 10 '16 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\$
-3
\$\begingroup\$

var i=0;
function printNo()
{
document.write(i+" ")
i++;
}
var stInt=setInterval;
var callSet=stInt(printNo);

\$\endgroup\$
  • \$\begingroup\$ Use "clearInterval" to stop the function like below clearInterval(callSet); \$\endgroup\$ – Rakesh Gm Jan 12 '15 at 7:52

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.