1

Is there any difference between the following? Do they all work in the same way?

I've seen certain use-cases for .call() but I've never seen an explanation as to why the function call brackets are either inside or after the anonymous function declaration.

(function() {

}());
 ^^
(function() {

})();
  ^^
(function() {

}).call();
Ben Fortune
  • 31,623
  • 10
  • 79
  • 80
  • SO's search needs to up it's game, as I couldn't find the duplicate. – Ben Fortune Dec 17 '14 at 17:02
  • Well, that question doesn't ask about `call`, which is why I reversed myself when I closed this as a duplicate originally (and now can't reverse Bergi's having done so). – T.J. Crowder Dec 17 '14 at 17:04
  • @T.J.Crowder: Hm, this question seems to be mainly interested in "*why the function call brackets are either inside or after*". Admittedly, multiple questions in one post are never good :-) Ben, if you want to know about `.call`, have a look at https://stackoverflow.com/questions/16937022/iife-invocation-in-javascript, I've never seen `.call()` without arguments though. – Bergi Dec 17 '14 at 17:10

3 Answers3

3

The first two are the same, and differ by style only*; the last one is different in that it gives you the ability to control what the value of this will be inside the IIFE. For example

(function(){
    this.a = 12;
}).call(foo);

will add the property a to the object foo.


*Of course Douglas Crockford has a preference

Adam Rackis
  • 82,527
  • 56
  • 270
  • 393
2

The location of the () inside or outside the main () doesn't matter in the slightest. (Much) more discussion in this other question, but that question doesn't address the call option you raised.

call requires at least one argument according to the specification, so to be largely the same as your first two options, you'd want:

(function() {
}).call(undefined);

...to be sure some implementation doesn't get uppity with you for not supplying the argument.

Community
  • 1
  • 1
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • 2
    So, we meet again, TJ Crowder... – Adam Rackis Dec 17 '14 at 17:01
  • I don't see how `call` requires any arguments? `.call()` is just equivalent to `.call(undefined)` as always. – Bergi Dec 17 '14 at 17:06
  • @Bergi: No, the spec doesn't say it's optional. There's a difference between calling `foo()` and `foo(undefined)` -- in the former, we're calling without any arguments (`arguments.length` is 0); in the latter, we're calling with `undefined` as an argument (`arguments.length` is 1). As the spec doesn't list `thisArg` as optional, I wouldn't leave it off, even if most implementations wouldn't care (which may or may not be true, I've never tested it). – T.J. Crowder Dec 17 '14 at 17:08
  • Was just about to ask, why doesn't it throw an error when omitting arguments to `call`. – Ben Fortune Dec 17 '14 at 17:08
  • @BenFortune: Tolerant implementation. :-) Say you have `function foo(arg)`: In **JavaScript**, you'd have to go out of you way in your `foo` code to tell the difference between being called via `foo()` or `foo(undefined)`, because `arg` would have the value `undefined` either way. (You'd have to check `arguments.length`) But the underlying implementation of `Function#call` isn't likely to be in JavaScript, so relying on that would be a bad idea. – T.J. Crowder Dec 17 '14 at 17:09
  • Of course `arguments.length` is different, I meant that the one formal (non-optional) parameter is filled up with `undefined` as described in http://www.ecma-international.org/ecma-262/5.1/#sec-10.5 - `.call()` is a plain function call after all. I'm pretty sure that it's forbidden to throw exceptions that are not explicitly described in the spec. – Bergi Dec 17 '14 at 17:18
0

I prefer 2nd way. JSLint uses the first way. You should always use .call() with an argument, so the third variant is wrong.

There is no difference between 1 and 2 though.