Take the 2-minute tour ×

The following is a method for defining an anonymous function within a closure, invoke the function, and forget it:

(function () { "do stuff"; })();

This is used to maintain a limited scope without adding bulk to the script (IIFE: Immediately-Invoked Function Expression).

What if you're hoping to immediately execute a function, while still retaining the function for future use, like the following:

var doThing;
(doThing = function () { "do stuff"; })();

This works in the browsers I've tested (Chrome, FF, IE8, IE10), but this does not pass JSLint (Bad Invocation). Are there any compatibility issues with doing it this way?

Is there a way of accomplishing this that is looked kindly upon by JSLint?

share|improve this question
If your function body was return 10;, wouldn't doThing be defined as 10 instead of the function itself? –  Cory Sep 10 '12 at 20:38
@Cory No, the parens are around the assignment. Easy enough to test, right? –  Dave Newton Sep 10 '12 at 20:45
@DaveNewton: Ah, thanks for pointing that out. –  Cory Sep 10 '12 at 21:22
add comment

5 Answers

up vote 2 down vote accepted

If passing jslint is absolutely necessary then:

var doThing;
(doThing = function () { "do stuff"; }).call();

should do the job.

share|improve this answer
Awesome! The whether this is actually useful is still up in the air, but this definitely answers the question. Thanks! –  Aejay Sep 11 '12 at 13:15
Same length as: var doThing = function() { "do stuff"; }; doThing(); with same end result but far less clarity (but yes, answers the question) –  Matt Whipple Sep 11 '12 at 13:30
You're right; it's not practical. Better to try to find a new method of solving old problems, and fail, than to resolve to always use the same method you've always used. Failure promotes progress. –  Aejay Sep 11 '12 at 13:45
add comment

You cannot or at least certainly should not assign a function reference and invoke the function at the same time. This kind of thing would easily cause heads to explode, as it would add to the already existing possibilities of assigning a variable to a reference, assigning a variable to a return, or assigning a variable to the result of an assignment. The way to do so anyone else would be able to read your code would be to do it in 2 lines. If you want to wrap that in a function it would be something like:

var doThing = (function() {
  var inner = function() {
     //doThing body
  return inner;

That by itself buys you nothing but obfuscation over doing it the simple way since the invocation wouldn't stick around regardless. You could however, if you really wanted create a function that does this:

var callAndRef = function(funk) {
  return funk;

and then

var doThing = callAndRef(function() {
//doThing body

or if you were feeling even fancier and have JS gurus working with you, you could throw it on to the Function.prototype and chain it off the declaration. You can also pepper in call/apply to maintain the this reference and arguments (but it seems like that would just be noise for your present question).

All of this should be done with extreme prudence it's certainly not worth going this route to save yourself having to type a couple extra lines of one command each.

share|improve this answer
This question is more on the side of curiosity than practicality :) . I like this response, but I think CD Sanchez's code more directly answers the question. I'm curious as to how one performs over the other, though. –  Aejay Sep 11 '12 at 13:13
His would most likely perform better and is more concise. The disadvantage is that it takes advantage of using the result of an assignment which generally seems to be discouraged in the languages that support it as it greatly confuses novices and can still trip up those with experience. –  Matt Whipple Sep 11 '12 at 13:18
add comment

A slight reordering of your code will help.



share|improve this answer
That is actually slightly different ... var doThing = function () { "do stuff"; }; doThing = doThing(); would be the equiv of what the OP is looking for. That said, it is an awkward and non-standard way to write it. –  Jeremy J Starcher Sep 10 '12 at 20:35
@JeremyJStarcher He wants to immediately invoke a function, and save it for future use. That is exactly what the code I wrote does... –  dqhendricks Sep 10 '12 at 20:37
@dqhendricks: But he also wants to "maintain a limited scope". You're executing doThing() in the global scope. –  Cory Sep 10 '12 at 20:38
@Aejay You could return arguments.callee from within your function, which would basically return the function itself in order to do what you are hoping to do, but it is being debated whether arguments.callee will be depreciated or not in future ECMA script versions. –  dqhendricks Sep 11 '12 at 15:43
@Aejay basically var somefunction = ( function() { // do something; return arguments.callee; } )(); –  dqhendricks Sep 11 '12 at 15:46
show 3 more comments

JSLink is Crawford's personal opinion on how Javascript should be written. Most of it is excellent advice, but sometimes his opinion seems to get into the way.

This is the more "standard" way to write that line:

var doThing = (function () { "do stuff"; }());

Note the whole (function ...) is inside the parens.

share|improve this answer
True Crockford suggests that, but it does not answer the question. How to invoke AND call it later. –  epascarello Sep 10 '12 at 20:36
@epascarello -- Then I must be misunderstanding the question. –  Jeremy J Starcher Sep 10 '12 at 20:36
'doThing' doesn't bind to the function with this code. However, I would tend to agree that Crawford's opinion shouldn't be treated too religiously. The OP is looking to save the closure from the function in doThing, and invoke it (at least that's how I interpreted it). –  Bubbles Sep 10 '12 at 20:37
add comment

If you only want to fix the Bad Invocation problem you can do this:

var doThing;

By splitting the declaration and assignment you make your code easier to understand and to maintain. Another option is to declare a function with a name:

function doThing() { "do stuff"; }
share|improve this answer
add comment

Your Answer


