30

While looking at code on github, I found the following:

(function() {

}).call(this);

This is clearly a self invoking anonymous function. But why is it written this way? I'm used to seeing the canonical variant (function() {})().

Is there any particular advantage to using .call(this) for a self invoking anonymous function?


Edit: It looks like some commonjs environments set this to a non-global value at the top level of a module. Which ones, and what do they set this to that you might want to preserve?

Sean McMillan
  • 10,058
  • 6
  • 55
  • 65
  • Possible dup of http://stackoverflow.com/questions/36636/what-is-a-closure – Rob Raisch Jun 09 '11 at 02:43
  • 2
    @Rob I don't think that's remotely what Sean is asking about in this question. – Matt Ball Jun 09 '11 at 02:46
  • 1
    Ah, found it - definitely not a duplicate question, but the answer is similar: http://stackoverflow.com/questions/5211638/pattern-for-coffeescript-modules/5212449#5212449 – Matt Ball Jun 09 '11 at 03:09
  • Ooh, Good link @Matt. I can see there that it makes a lot of sense if the functions are nested. – Sean McMillan Jun 09 '11 at 03:27
  • http://stackoverflow.com/questions/4542942/why-use-the-javascript-function-wrapper-added-in-coffeescript-callthis/4542979#4542979 A comment on this answer says that some commonjs environments set `this` to a non-global at the top level of a module. That would explain why you might need to preserve `this`. – Sean McMillan Jun 09 '11 at 04:58
  • http://stackoverflow.com/questions/5995510/expose-a-javascript-api-with-coffeescript/5995586#5995586 It looks like it's node that sets `this` to non-global for modules. A comment here says that `this === exports` in the node environment. – Sean McMillan Jun 09 '11 at 12:41
  • If you wonder why `.call(this)` was used instead of the normal IIFE call, see [my answer](http://stackoverflow.com/a/21736430/1048572) on "Why write “.call(this)” at the end of an javascript anonyms function?" – Bergi Feb 12 '14 at 18:29

5 Answers5

27

By default, invoking a function like (function(){/*...*/})() will set the value of this in the function to window (in a browser) irrespective of whatever the value of this may be in the enclosing context where the function was created.

Using call allows you to manually set the value of this to whatever you want. In this case, it is setting it to whatever the value of this is in the enclosing context.

Take this example:

var obj = {
    foo:'bar'
};

(function() {
    alert( this.foo ); // "bar"
}).call( obj );

http://jsfiddle.net/LWFAp/

You can see that we were able to manually set the value of this to the object referenced by the obj variable.

user113716
  • 318,772
  • 63
  • 451
  • 440
  • 1
    His question asks what adding `this` to the end does, not what adding a custom object does. – Startec Jan 06 '15 at 06:56
  • @Startec: There's no difference. They'll do the same thing. He's just passing a different object so he can show that the properties of the object become available via `this` inside the function. – six fingered man Jan 13 '15 at 03:49
  • 1
    @sixfingeredman Right, this shows that you can set the value of this by passing in an object in the closing parens. However, the question is, what happens when you pass in the `this` object, not some object you have instantiated. In other words, if passing in `this` just makes the value of `this` in the enclosing function `this`, why pass it in at all? – Startec Jan 13 '15 at 06:02
  • @Startec: I see what you're saying. Since they would be effectively the same (unless in strict mode), then what's the point. Though that rationale is based on global execution of the IIFE, and that detail seems to have been added to the question a bit later. – six fingered man Jan 13 '15 at 17:33
  • Is there an ES2015 way of doing this? – Gus Mar 22 '16 at 17:48
7

.call(this) (was actually just () until I changed it) ensures your top level this to be consistent through strict mode, --bare option and/or the running environment (where top level this doesn't point to global object).

matyr
  • 5,774
  • 28
  • 22
  • 19
    None of that makes any sense. – RobG Jun 09 '11 at 12:10
  • 8
    Ah -- `()` and `.call(this)` are different in strict mode. Now it all makes sense. `.call(this)` provides the same context to the function is strict and lax modes. – Sean McMillan Jun 09 '11 at 12:31
  • 1
    @matyr Can you explain further with description or links about () and .call(this) what they are actually means in strict mode? I could not understand the strict mode bit. – Ravi Mar 17 '14 at 16:53
  • 12
    In lax mode, if you call a function with no object, `this` is set to `window`. In strict mode, `this` is set to `undefined`. Using `.call(this)` explicitly sets `this` (inside the function) to `this` (outside the function), thus making sure that it stays as `window`, regardless of if you are in strict or lax mode. – Sean McMillan Mar 18 '14 at 15:17
  • Thanks, @SeanMcMillan. I actually understood what you wrote. I believe your explanation was much better than the answer. – Con Antonakos Mar 18 '15 at 17:30
0
C={
    descript: "I'm C!<br>",
    F: function() {
        //set this to the caller context's 'this'
        (function() {
            document.write(this.descript);
        }).call(this);

        //set this to 'window' or 'undefined' depend the mode
        (function() {
            document.write(this.descript);
        })();

        //member function's 'this' is the object self
        document.write(this.descript);
    }
}

window.descript="I'm window!<br>";

C.F();

(function() {}).call(this); could set the this in the anonymous to the caller context this, in above is C.(function() {})(); will set this to window or undefined depend the mode.

Lee Li
  • 392
  • 2
  • 5
  • 11
0

By using:

> (function() {
>   ...
> }).call(this);`

then this in the scope of the code (probaby the global object) is set as the function's this object. As far as I can tell, it's equivalent to:

(function(global) {
  // global references the object passed in as *this*
  // probably the global object
})(this);

In a browser, usually window is (or behaves as if it is) an alias for the global object.

RobG
  • 142,382
  • 31
  • 172
  • 209
  • 1
    The first is definitely not equivalent to the second. – Matt Ball Jun 09 '11 at 03:10
  • 1
    It provides a reference to the outer execution context's *this* and stores it as a local variable named *global* rather than *this*. So it is equivalent, it just assigns the reference to a different property of the local activation/variable object. – RobG Jun 09 '11 at 05:45
-3

Self-invoking function are useful to execute its content immediately when the script is loaded. This is convenient to initialize global scope elements.

Freeman
  • 5,810
  • 3
  • 47
  • 48