Reason Behind This Self Invoking Anonymous Function Variant

Reason behind this self invoking anonymous function variant

.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).

Anonymous self-invoking function is automatically passed as an argument to above declared local function. Why?

Remove some newlines and you can see why:

let myfunc = function(a) {
return function localScope(b) {
console.log(a + b + " this")
}
}(function () {
console.log('test')
})()

And function(){}() is actually valid syntax to call that anonymous function. You can use a defensive semicolon to properly split the statements:

let myfunc = function(a) {
return function localScope(b) {
console.log(a + b + " this")
}
};

(function () {
console.log('test')
})()

Not self invoking anonymous functions

"Q: Is that just preference you think?"

Yes, but using a unary ! operator, you can avoid a few bugs when you forget a semicolon before the IIFE, which can cause the () to be interpreted as a function call.

alert('foo')  // alerts 'foo'

(function() { // TypeError: undefined is not a function
alert('bar');
})()

Here the outer () is interpreted as a function call. It's trying to call whatever was returned from the alert() function, which of course returns undefined, which isn't a function.


alert('foo')  // alerts 'foo'

!function() {
alert('bar'); // alerts 'bar'
}()

No troubles with this one, since the ! is a unary operator that only evaluates the operand to its right.

Why write .call(this) at the end of an javascript anonymous function?

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.

Why use (function(){}).call(this);?

Let's disassemble this piece of code.

First off there is an anonymous function with immediate invocation. It's similar to this:

(function () {/**/}).call();
(new Date()).getTime(); // timestamp since 1970 jan 1 in milliseconds

We don't assign new Date() to a variable, instead we use it immediately.


Now why use .call instead of just ()?

.call is a method all Functions have. The first argument is what this will be bound to, subsequent arguments will be passed as arguments to the function. So:

(function () {
console.log(this.foo); // bar
}).call({ "foo": "bar" });

This works in conjunction with undefined (see below).

.call is the same as .apply with one minor difference. .apply only takes 2 arguments, where the 2nd is an array of arguments. This would be similar:

(function () {}).call(this, "foo", "bar");
(function () {}).apply(this, [ "foo", "bar" ]);

A common use of apply is in conjunction with the magic variable arguments.

(function () {
console.log(Array.prototype.slice.call(arguments, 1)); // [ "bar" ]
})([ "foo", "bar" ]);

Array.prototype.slice.call(arguments, 1) may look scary but really it's just arguments.slice(1), but arguments isn't an Array so it doesn't have a slice function. We borrow Arrays slice function and use .call to set the this to arguments. Array.prototype.slice(arguments, 1??) is incorrect.


Now why is there this in .call(this)? this always points to the context you're in. If you're in an instance of a class it will point to the instance and if you're in the global scope it will point to that. In a browser environment it is also window.


Why undefined? Since we did a .call(this) with no second argument, all arguments to our anonymous function are undefined. I'm not really sure why you need to make an explicit variable named undefined there. Maybe this is support for some browsers or some lint tool that likes to see undefined defined.

Thanks to @TedHopp. undefined is fickle.

var undefined = "foo";
console.log(undefined); // undefined

(function (undefined) {
console.log(undefined); // "foo"
})("foo");

You can just as easily have:

(function () {
/* code here */
}());

This is completely valid and works just the same. There might be some performance or linting benefits to use the form you posted.

self executing function invoked explicitly with call method

The second form passes the value of this into the IIFE so this inside the IIFE will have the same value that it had outside the IIFE. There are many cases where this does not make a difference, but if the IIFE is inside a scope where this is set to some meaningful value, then the second form will preserve that value of this inside the IIFE.

If this in the outer scope is the global object and you are not running strict mode, then the 2nd form doesn't really change anything as this will still be the global object inside the IIFE.

But, if this is any meaningful value in strict mode or any meaningful value other than the global object when not in strict mode, then the 2nd form will extend the value of this into the enclosure.

In the example you point to, my guess is that the second form is just being used as a common design pattern, not because there really is a reason in that particular case to do it. In fact, if you look at the code example you pointed to, it doesn't even use the value of this at the top level of the IIFE so it's definitely superfluous in that specific example.

Why is .call(this) used instead of parenthesis

Presumably the code within that function uses this (where you just have console.log). In the version with call, this within the function is the same as this outside it. Without call, this inside the function is either the global object (loose mode) or undefined (strict mode).

If you're not using this within the function, there's no reason to be doing the call version, and I would lean toward not doing so because it's additional unnecessary complexity (and apparently a very very small performance cost).

Manually invoking anonymous JS function

You're close, the attempt you've shown is just not invoking it;

function confetti() {
// pass
}
confetti.call(this);

However as you want to use it elsewhere, I won't assume this will be the same, so instead I would write

var confetti = (function () {
// pass
}).bind(this);

confetti();

You can read the docs on call here and bind here

Why would any body use this pattern?

Probably the writer wants to change the context of the IIFE. Passing this would be pointless, since it will refer to window even without the call.

Something like this would change the meaning of this in the scope:

(function () { console.log('Hello World', this) }).call({foo:1});

However, I still don't see the point, since you might as well do it like this:

(function (fooObj) { console.log('Hello World', fooObj) })({foo:1});

Which I would say is more common to see.

Why use the javascript function wrapper (added in coffeescript) .call(this)

It's creating a function and then calling itself with the parent function/objects scope.

.call and .apply are different methods of invoking a function. You basically created a function that does nothing except set a=1 within its own scope.

In javascript you need to realize that every function is a object, and this is what refers to the current object/function. Using .call(this) overrides this from within the function and replaces it with the one from the calling context.



Related Topics



Leave a reply



Submit