67

Is there a way in Javascript to define a function and immediately call it, in a way that allows it to be reused?

I know you can do one-off anonymous functions:

(function(i) {
    var product = i * i;
    console.log(product);
    // Can't recurse here because there's no (ECMA standard) way for the 
    // function to refer to itself
}(2)); // logs 4

Or you can name a function then call it afterwards:

function powers(i) {
    var product = i * i;
    console.log(i * i);
    if (product < 1e6) { powers(product) };
}

powers(2); // Logs 4, 16, 256...

But is there a cleaner way of defining and calling a function in one go? Sort of like a hybrid of both examples?

Not being able to do this isn't preventing me from doing anything, but it feels like it would be a nice expressive way to write recursive functions or functions that need to be run on $(document).ready() but also later when situations change, etc.

hippietrail
  • 15,848
  • 18
  • 99
  • 158
quis
  • 1,120
  • 2
  • 8
  • 15
  • Possible duplicate of [Can I name a javascript function and execute it immediately?](http://stackoverflow.com/questions/6404196/can-i-name-a-javascript-function-and-execute-it-immediately) – brichins Mar 23 '17 at 15:43

4 Answers4

60

You can try:

(window.powers = function(i) {
  /*Code here*/
  alert('test : ' + i);
})(2);
<a href="#" onclick="powers(654)">Click</a>

Working link : http://jsfiddle.net/SqBp8/

It gets called on load, and I have added it to an anchor tag to change the parameter and alert.

Mosh Feu
  • 28,354
  • 16
  • 88
  • 135
Marc Uberstein
  • 12,501
  • 3
  • 44
  • 72
41

If all you want is access the function within its own body, you can simply specify a name after the function keyword:

> (function fac (n) {
    return (n === 0 ? 1 : n*fac(n-1));
  })(10)
3628800

This is a standard feature (see ECMA-262, ed. 5.1, p. 98).

Matthias Benkard
  • 15,497
  • 4
  • 39
  • 47
15

All the answers here are close to what you want, but have a few problems (adding it to the global scope, not actually calling it, etc). This combines a few examples on this page (although it unfortunately requires you to remember arguments.callee):

var test = (function() {
  alert('hi');
  return arguments.callee;
})();

Later, you can call it:

test();
gkoberger
  • 476
  • 4
  • 11
  • 2
    The only problem is that arguments.callee is [deprecated](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions_and_function_scope/arguments/callee) and throws an error on ES5 in strict mode. – Tivie Jul 02 '14 at 01:12
  • 5
    @Tivie But you can name the anonymous function. `var test = (function fn() { alert('hi'); return fn; })();` – Evan Kennedy Aug 04 '15 at 20:20
6

If you don't care about the return value, you can do this.

var powers = function powers(i) {
    var product = i * i;
    console.log(i * i);
    if (product < 1e6) { powers(product) };
    return powers;
}(2);
twhb
  • 4,294
  • 2
  • 20
  • 23