Difference between anonymous functions - javascript

I'm reading more open source javascript frameworks and found more ways of how to create anonymous functions, but whats is different and best way?
(function() {
this.Lib = {};
}).call(this);
(function() {
var Lib = {}; window.Lib = Lib;
})();
(function(global) {
var Lib = {}; global.Lib = Lib;
})(global);

(function() {
this.Lib = {};
}).call(this);
Defines the Lib property of the Object it's called on, and is immediately called on this which is typically the window. It may instead refer to the Object that owns the method in which it is called.
(function() {
var Lib = {}; window.Lib = Lib;
})();
Defines the Lib property of window regardless of where it's called (although it's also called immediately).
(function(global) {
var Lib = {}; global.Lib = Lib;
})(global);
Defines the Lib property of the object passed to the function. It's called immediately, but will result in an error unless you've defined a value for global in the current scope. You might pass window or some namespacing Object to it.
These aren't actually different ways of defining "anonymous functions", they all use the standard way of doing this. These are different methods of assigning values to global (or effectively global) properties. In this sense, they are basically equivalent.
Of more significance would be, for instance, how they define methods and properties of the objects they return/construct/expose (that is, how they build Lib itself).
All of these functions return undefined and only the first could be usefully applied as a constructor (with the use of new), so it would seem they are nothing more than initializers for the frameworks.

All of them are effectively equivalent (but less efficient and more obfuscated) to:
var Lib = {};
Immediately invoked function expressions (IIFEs) are handy for contianing the scope of variables that don't need to be available more widely and conditionally creating objecs and methods, but they can be over used.
Note that in the last example, I think you mean:
(function(global) {
...
})(this);

Check out this question: Why do you need to invoke an anonymous function on the same line?
It contains a whole lot of information about anonymous functions. Check out this question as well: var functionName = function() {} vs function functionName() {}

Related

Expose an object's member functions as global functions

For example I have:
var n = {
abc: function() { print("abc"); },
def: function() { print("def"); },
};
Is there a way to export abc and def as global functions, so that I can call abc() directly rather than n.abc()?
My context for this is using Rhino/Nashorn script engine, and I'd like to inject a "global" object that provides global functions.
The answers for Rhino and Nashorn would be different.
For Rhino, when you create the global object using Context.initStandardObjects, you can then add your properties on the Java side by calling ScriptableObject.defineProperty (see Rhino API) and then the properties will be added to that global scope. If you need a property of type function as your example shows, create it using the FunctionObject API.
For Nashorn, you can use the interfaces mostly based on the standard javax.script APIs, with a couple of Nashorn-specific extensions. When evaluating your script, first use ScriptEngine.createBindings() to create a Bindings object, then use Bindings.put to use eval(String/Reader,Bindings)
If you need a function property, then on the Java side call ScriptUtils.wrap to create a ScriptObjectMirror (make sure to cast it to that; return type of the method is Object), then call get([function name]) to get an executable function property, then put that in the global scope.
All of that said, it seems to me that this is more easily handled on the script side using:
var abc = function() { return n.abc.apply(n,arguments); };
That's portable across Rhino/Nashorn and is one line, which is a lot less work than what you're going to do if you want to avoid writing that one line.
If you execute that in the global scope, you don't need a qualifier; it'll be added to the top-level object as a property. If you want to be more explicit you can do something like this:
(function() {
var global = this; // inner functions called without target default to global as 'this'
this.abc = function() { return n.abc.apply(n,arguments); };
})();
... which will work unless you start doing stuff that's a lot fancier (like messing around with 'this' values when loading scripts).
Why don't you just use JavaScript's bind, call and apply methods to call the object's member functions when you need to invoke them? Making them global indicates code smell.

Correctly defining an object

I have been working on a JS project and having never worked on a proper JS project before I installed JSHint to keep my JS in line. This lead to me looking at the "use strict" definition which lead to me reading about anonymous functions. Now I'm real confused. I don't know how to properly define my object.
I decided to look at some public js libraries (mainly Bootstrap) on how they do things.
This is the general pattern I see:
(function($) {
'use strict';
var MyObject = function() {
// ...
}
// Prototype methods
})(jQuery);
My questions is how do outside scripts then see the object? I want to be able to pass the object two ids from the initializer.
It's an IIFE (immediately invoking function expression).
It purposefully doesn't create global variables. It's used to keep the namespace clean. It's also passing the $ variable (defined as jQuery) as an argument so that it has access to jQuery without pulling in any other libraries that may use the $ sign that the user might be implementing.
I think you may want to look more into the constructor/module/prototypical inheritance patterns, and do some research in to why IIFEs are used (what situations they are good for/bad for).
If you want to use an IIFE and have a function that passes it arguments, or define the argument variables from inside (without polluting the namespace), you can just do it from inside your IIFE.
Off the top of my head example:
(function(){
var Foo = function(arg){
};
Foo.prototype.something = function(){
do something;
};
var Bar = function(){
do something;
return arg;
};
var baz = new Foo(bar());
baz.run();
//or
var ex = something you want to pass as an arg;
var baz = new Foo(ex);
baz.run();
})();
You can export MyObject in the following way
(function(window){
var MyObject = function....
MyObject.prototype. something...
window.MyObject=MyObject;
}(window));
More on constructor functions,prototype and inheritance here:https://stackoverflow.com/a/16063711/1641941

Understanding javascript functions, scope and closures

Can someone explain in detail what this snippet of js does?
(function (window) {
var test = window['test'] = {};
test.utils = new(function(){ ... })();
})(window);
I understand that the function is not globally scoped. I understand that it is creating a variable called test that points to a property in the window object that is an empty object. I also understand that utils is a property of test.
I don't understand what the purpose of the last part is (window); or why the utils function is being designated as new.
Please explain.
It creates a function and calls it immediately, passing in window. The function receives an argument called window and then creates an empty object on it which is available both as a property on window called test and as a local variable called test. Then it creates an object by calling a function via new and assigns that object to test.utils.
I don't understand what the purpose of the last part is (window);...
It doesn't really serve any purpose in the code you've quoted, because the symbol passed into the main (outer) function, window, is the same as the name of the argument receiving it. If their names were different, then it would serve a purpose, e.g.:
(function(wnd) {
})(window);
That would make window available within the function as wnd.
or why the utils function is being designated as new.
utils won't be a function (at least, not unless the code you've replaced with ... is doing something really strange), it will be an object created by calling that function.
The whole thing could be rewritten more clearly:
(function(window) {
var test;
test = {};
window['test'] = test;
test.utils = new NiftyThing();
function NiftyThing() {
}
})(window);
That still does the window thing for no reason, but hopefully it makes it clear what the new(function() { ... })(); bit was doing.
First of all, this is a self-invoked function.
It's invoked itself giving the window object as function input argument in order to ensure that, inside the whole function, window will have the expected meaning.
test.utils = new(function(){ ... })(); <--- This is an object constructor.
When the function is called using the new operator, it turns into an object constructor.
For example:
var conztructor = function() {
this.name = "Matias";
};
var obj = new conztructor();
alert(obj.name); // <--- This will alert "Matias"!
The purpose of (window); is creating a new variable and reference holding the JavaScript Window object instance, avoiding that other libraries may reuse the window (or any other) identifier and your own library may break because of this situation.
This is nice in order to avoid altering global scope identifiers that may be used by other libraries.
UPDATE
In response to some comments, run this code:
http://jsfiddle.net/wChh6/5/
What is happening here is that a new anonymous function is being declared. The last part with (window) makes a call to that function, passing window as a parameter.
Inside, the call to test.utils = new(function(){ ... })(); creates a new object (with contents defined by the function passed to new) and assigns it to test.utils.
When you define a function with last parentetheses, the function is executed itself after loading with the parameter given, in your case window
(function (window) {
var test = window['test'] = {};
test.utils = new(function(){ ... })();
})(window);
JS function definition : meaning of the last parentheses

JavaScript: module pattern differences

What is the difference between
var module = (function(){
return {}
})()
and
(function(context){
var module = {}
context.module = module;
})(this)
A property of this is not equivalent to a variable. In the global scope (i.e. where this references window), they are similiar. Yet, for example they will have a different behavior when you try to delete them:
> this.module = {};
> delete this.module
true
> var module = {};
// cant be deleted
Apart from that, both snippets create an empty object, wrapped inside a closure where you could define local (private) variables/functions etc. In your second function the object is also assigned to the local variable module, but that could be done in the first one as well.
#Eric: Your approach, using the new operator, is similiar to the first one regarding the variable. However, it will create an instance of that anonymous function instead of returning a plain object. It will inherit properties from a custom prototype, so for example module.constructor will then point to the anonymous function (which cannot be garbage collected, but e.g. even reused to create a clone). I would not recommend to use this.
Top one is revealing module pattern. It lets you define private functions (as much as you can in javascript) and choose which ones are made public via the return call.
var module = (function(){
function foo() {}; // Public, since it's returned
function bar() {}; // Private, since it is not returned
return {
foo: foo
}
})();
The bottom one, as far as I can tell, just assigns an object literal to another object's namespace. It's probably the start of a singelton pattern.
(function(context){
var module = {};
context.module = module;
}(this)
The module could actually be defined with the revealing module pattern, hard to say since in your example it's just an object literal.

Javascript modules: return a bare object, or name it

Using the Javascript module pattern, what are the advantages/dis-advantages of returning a bare object containing the interface, versus creating a named object containing the interface, then returning a reference? Example code below. I always put the interface into a named object, and the one advantage I see of this is I can do some debugging before I return it.
function bareObjectModule() {
return {
method1: function() {}
//etc.
}
}
function namedObjectModule() {
var namedObjectModule = {
method1: function() {}
}
//debug here?
return namedObjectModule;
}
The main advantage of returning the interface directly is that it is short and does not include much boilerplate but having a named reference is much more powerful and allows for other patterns that you could not originally. The biggest advantage is that it is much easier to have the functions reference each other if you have a reference to the module
var M = {};
M.f1 = function(){ ... };
M.f2 = function(){ M.f1() }; //functions can reference each other without
// a fragile dynamic binding through `this`
M.f3 = some_combinator(M.f2); //since you are not limited to defining things as
//property-value pairs you have much more flexibility..
return M;
Other than the debugging advantage you mentioned, i see no difference whatsoever in the 2 approaches. Since namedObjectModule is function local it'll anyway be discarded once the function returns (i.e. the variable name in the stack).
One minor point might be that with a named object, there will be a stack entry for the local variable 'namedObjectModule' (will be popped out once the function returns), and there will be an entry in the function call stack (to the same object) for the return to work. With bare object, the former can be avoided. Not sure if this has any real performance impact, unless you have thousands of objects in the stack.
The main difference is that with a referenced object you can use properties and call methods from other methods. You can't do that with a single object literal.
As an alternative to both approaches, you can call the enclosing function as a constructor (with new) and have it return this object to export the module.
var myModule = new function () {
this.methodA = function () { /* ... */ }
this.methodB = function () { /* ... */ }
console.log(this) // debug
}
No need to type return explicitly (constructors return this by default) and define an object literal (and come up with a name) as a bonus.

Categories