Brackets wrapping of functions - (function() { }) () , and `.call()` - javascript

I have been writing javascript for a while now and more recently been playing with coffeescript. I noticed that coffeescript compiles functions in the following way:
(function() {
}).call()
I have also noticed people write functions in this way:
(function() {
})()
From what I understand these are anonymous functions that call themselves. Firstly, what is the difference in between having .call() and just () is .call() just a more semantic way of writing ().
Also why does coffeescript wrap the entire file in an anonymous function, when it isn't usually necessary? Are there any performance or other advantages to this? When should these sort of self calling anon functions be used?
Thanks

Using .call() changes the context of the IIFE to the this value of the parent scope.
The first this will be [object Window], the global scope in browser environments:
(function () {
console.log(this);
})();
The second, will be the exact same:
(function () {
console.log(this);
}).call(this);
The difference is that in ECMAScript 5's strict mode, the first example this will be undefined:
(function () {
'use strict';
console.log(this); // undefined
})();
However when using Strict Mode and .call(), this is again the global scope with the correct this context:
(function () {
'use strict';
console.log(this);
}).call(this);
Here's a jsFiddle showing this. The main difference is that the normal IIFE loses it's this context, some CommonJS platforms evaluate files with a specific this.
CoffeeScript does this to ensure that your code has the same this context as the scope where it's placed (the parent scope) - because functions don't normally inherit their this object from the surrounding context.
Using the pattern(s) above, you should wrap your function logic in there to avoid placing all your code in the global scope and having variable/naming conflicts, to which you can then create things such as Modules and return only the APIs that you need, for instance:
var Module = (function () {
'use strict';
return {
someMethod: function () {
// do something
}
}
})();
// call it:
Module.someMethod();
Each function creates it's own scope, so wrapping your blocks of code in these will protect your variable/function names from conflicting with eachother. We can also access "private" methods from within these closures:
var Module = (function () {
'use strict';
var _privateMethod = function () {};
return {
someMethod: function () {
_privateMethod();
}
}
})();
We would do this when we don't want the methods to be publicly accessible by our users too.

Related

JavaScript Module assignment pattern

I am reading A JavaScript Module Pattern, and wondering why bother to do the module assignment by firing an immediate anonymous function call like this:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.",
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
}
};
}();
instead of directly assign the object to YAHOO.myProject.myModule like this:
YAHOO.myProject.myModule = {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.",
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
}
};
In that example, there isn't any point. You didn't read enough of the document you linked to.
Section 3 is Add "private" methods and variables in the anonymous function prior to the return statement., and that demonstrates why you would want to use an IEFF here.
It is so you can define local variables which are accessible to the functions you are making public, but aren't directly accessible themselves.

Should I namespace functions and classes?

I've been reading through some global scare articles, you can thank Crockford for this question.
For instance, I have a function I've defined as:
function httpRequest() {}
This is a pretty generic function name, which could potentially be used in a thirdparty library. Should I just make it a habit to attach the function to an app namespace?
APPNAME.httpRequest() {}
I read through Google's style guide for JavaScript and they recommended this for variables, what about functions and classes?
APPNAME.MyClass = (function () {
'use strict';
function MyClass() {}
MyClass.prototype.myMethod = function () {};
return MyClass;
}());
EDIT:
Let's say I plan on combining with a lot of other libraries.
JavaScript variables are closure scoped. So you can always use an IIFE to encapsulate them:
(function(){
function httpRequest() { /* */ }
httpRequest(...);
})()
//httpRequest is not defined here unless it was defined above the block
You can also export stuff to the global namespace
var httpUtils = (function(){
return whatever; // whatever is exported, the other variables are internal
})()
Creating objects that encapsulate behavior like this and exposes some is called a module pattern.
You can use module loaders to manage your modules. One example is RequireJS.
require(["httpUtils","logger",function(http,log){
http.request(...); // uses from other module
log(..); // use other module
return { }; // the return values can be used in other modules, require by file name
// or explicit configuration
});
Namespacing is also an option, but it is generally less desirable.

How to return object literal in JavaScript

I'm trying to wrap a JavaScript object literal in a self executing anonymous function. The first code example below works fine, but the second doesn't and I'm not really sure why?
Works:
(function(){
return MyApp = {
init: function() {
console.log('MyApp init');
}
}
})();
Doesn't Work:
(function(){
var MyApp = {
init: function() {
console.log('MyApp init');
}
}
return MyApp;
})();
As I understand things, the SEAF should execute and immediately return. That's why the first example returns MyApp as an object I can interact with. I thought assigning MyApp to a variable inside the SEAF and then returning it would do the same thing but in:
Uncaught ReferenceError: MyApp is not defined
Why?
Since the result of your SEAF (better named IEFE) is not used anywhere, it doesn't really matter what the function returns. Now compare
(function(){
MyApp = {…}
})();
with
(function(){
var MyApp = {…}
})();
The difference is that in the second function your variable is preceded by a var keyword which makes it local to the IEFE, while in the first function it is an implicit global (which you should avoid). That way, the second snippet doesn't assign to anything in the global scope, and accessing MyApp later from outside will fail with the error.
Better return some value that you then assign to a globally declared variable:
var MyApp = (function(){
return {…};
})();
What your first example is doing is setting MyApp as a global variable - since the variable MyApp is not preceded by a var keyword or dot notation, it becomes global. It sounds like that's not actually an issue for you if you're putting MyApp in a self-executing function - you can really just remove the return statement from it - or even define other globals in the same function. You don't ever reference the result of your top-level function, so there's no use of that return.
Your second example sets MyApp as a local variable using var, so it's visible only inside of the context of the function that's running it.
Solution using arrow functions:
var myApp = (() => {
return {
init: () => console.log('MyApp init')
};
})();
myApp.init();
Explanation:
The global variable myApp is set to the result of an IIFE (Immediately-invoked Function Expression).
init can also be written as an arrow function.
If no other logic is performed in an arrow function before the return statement, and it returns an object literal, it can be further simplified. To return an object literal from an arrow function, wrap it in parentheses:
var myApp = (
() => ({
init: () => console.log('MyApp init')
})
)();

Firebug and self-invoking anonymous functions

My basic setup is a whole heap of Javascript under an anonymous self-invoking function:
(function () {
...
})();
My problem is that I can't seem to get access to the objects within this ASI function via the DOM tab. I tried both the following:
var MYAPP = function () {
...
};
var MYAPP = (function () {
...
})();
The first didn't fire at all. The second just said MYAPP is undefined in the DOM tab.
Is there a way around this?
In your first version, you are simply creating a function with the name MYAPP, but you are not executing it.
In the second version, your function is executed and its result is assigned to MYAPP. But your function does not seem to return anything, so MYAPP stays undefined.
See A Javascript Module Pattern on YUIBlog for an explanation of this pattern. Their example goes like this:
YAHOO.myProject.myModule = function () {
return {
myPublicProperty: "I'm accessible as YAHOO.myProject.myModule.myPublicProperty.",
myPublicMethod: function () {
YAHOO.log("I'm accessible as YAHOO.myProject.myModule.myPublicMethod.");
}
};
}(); // the parens here cause the anonymous function to execute and return
So your function basically returns an object containing all the public members. You can then access these with Firebug, too.

Make a function accessible outside of a closure

Is there a way to make function created inside a closure accessible outside of the closure? I'm working with an AIR app and I need to provide access to the specialFunction() to AIR but the closure is keeping that from happening.
(function () {
... a bunch of code ..
function specialFunction() {
.. some code
}
}());
You can assign the function to the global object (which is window in browsers):
(function () {
... a bunch of code ..
window.specialFuncton = function() {
.. some code
}
}());
This makes it globally available.
If the AIR application also needs access to other functions, then it is better to create a namespace for these functions:
var funcs = {}; // global
(function () {
... a bunch of code ..
funcs.specialFuncton = function() {
.. some code
}
}());

Categories