60

I have seen JavaScript written like this (it was at a demonstration, and I don’t have the actual code at hand, but it was implied this was normal):

(function() {    

    var a = 1;

    this.sayA = function() {
        alert(a);
    }

}).call(this);

sayA();

I suppose it is written an an anonymous function so that the variable a is not globally available.

What could the point of the .call(this) be? Since this function was not nested, this was just the window. How does it differ from just writing () at the end?

2
  • 1
    There should be no difference. It might just be a matter of coding style, to make invocation more apparent. Commented Nov 7, 2011 at 11:30
  • 3
    I think there is a difference. If the context is not the global scope, the anonymous function will act as a member function for whatever this might be. Would it not? Commented Nov 7, 2011 at 11:41

4 Answers 4

36

Try this:

function Foo() {

  (function () {
    console.log(this);
    // > Foo
  }).call(this);

  (function () {
    console.log(this);
    // > undefined in strict mode, or Window in non strict mode
  })();
}

var bar = new Foo;

So, if for whatever reason you use this, it's a way to make the IIFE act as if it were a member function of Foo, specifically when creating instances of a user-defined object type.

Sign up to request clarification or add additional context in comments.

4 Comments

but how is that different from var bar = function (){console.log(this) x 2;}
Is there an ES2015 best practice for this?
@Gus: Use an arrow function for your IIFE if you want the same this as outside. Or just block scope only.
I think some programmers must be simply overusing this technique in places where it doesn't make sense. For example: github.com/iabramo/brightcove-gtm/blob/master/dist/….
34

I was curious about this as well as I had just seen John Resig's talk about this video. Yoshi had a great answer but I had to test it in a bit in console log to understand and I thought this modification to his answer might help some people who were having trouble at first like me:

function Foo() {
  this.foo = true;
  (function () {
      console.log("Foo = " + this.foo);
      // Outputs undefined
  }());
  (function () {
      console.log("Foo = " + this.foo);
      // Outputs true
  }).call(this);

  (function () {
      console.log(this);
      // Outputs undefined in strict mode, or Window in non strict mode
      // Anonymous functions usually default to the global scope
  })();
}

var bar = new Foo;

It just made a little more sense to me to see the first and second ones side by side, showing that .call(this) essentially gives you the ability to pass the current context to an anonymous function.

Thanks for the question and thanks Yoshi for the clear answer!

Comments

15

Since this function was not nested, this was just the window. How does it differ from just writing () at the end?

No - not in strict mode:

  1. If the function code is strict code, set the ThisBinding to thisArg.
  2. Else if thisArg is null or undefined, set the ThisBinding to the global object.

In strict mode, the this is just directly set to the given value, which is undefined for a normal call. Therefore, .call(this) is used to pass the global object explicitly in. You can try this in the console:

> (function() { "use strict"; console.log(this); })()
undefined
> (function() { "use strict"; console.log(this); }).call(this)
Window

It might not make a difference for sloppy code, but it's a good practise and future-compatible :-)

Comments

14

this passed to the function sets the context of the execution, so inside your anonymous function this refers to the window.

You can than write this.alert('');.

3 Comments

thanks for the recommendation.
Could downvoter care to explain, please?
@Jakub. I've downvoted your answer because of "Not a common practice/I wouldn't recommend" part. It is a common practice and it's often recommended one. See for example: stackoverflow.com/questions/4542942/…

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.