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.
Related
I'm trying to get a really solid grasp of JavaScript and I'm stumbling across a big issue for me. I'm used to working in C languages and one of the barriers I'm finding is dealing with the prototype functionality of JavaScript and when functions are declared, as it is concerned with the order of execution.
For instance, take the following code:
var construct = new Constructor(); //I can do this even if its above the declaration of the object.
construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.
construct.MyPublicFunction(); //Can't do this because it is above the function declaration.
function Constructor() {
//Private member
var m_Ding = "Ding!";
//Accessible publicly and has access to private member.
this.MyPrivilagedFunction = function() {
console.log(m_Ding);
}
}
Constuctor.prototype.MyPublicFunction = function() {
//Doesn't have access to private members. This doesn't work.
console.log(m_Ding);
}
I understand that prototyping provides better performance because then a copy of the function is not stored on every instance of your object and instead every instance is referring to the same function (and I guess each new instance could be considered a whole new object type?). However, prototyping does not allow me to use a function before it is defined. Furthermore, a prototyped function doesn't have access to a private member of the object.
This is only really a problem because I am working on a project where two objects will need to use each other's functions. If I place one object earlier in the code, it won't have access to the second object because prototyped functions adhere to the order of execution (top to bottom).
Side Note: I'm also aware that my object should probably be an object literal ( like object={property:value}), but I'm still trying to get a solid grasp on scope and prototyping to attempt to deal with that for now.
if i get you well, the root of your problem is "two objects will need to use
each other's functions."
But in fact Javascript is not a typed language : define TypeA, define TypeB,
after that you can use instances : typeA and typeB objects with no issue.
var Speaker = function(name) {
this.name = name ;
};
Speaker.prototype.sayHi = function(aMate) {
amate.listenTo(this, ' Hi ' + this.mate.name ); // no type checking performed here
// so no issue even if Listener
// is not defined yet
};
var Listener = function(name) {
this.name = name;
this.knownMate = [];
};
Listener.prototype.listenTo = function (mate, words) {
this.knownMate.push(mate);
};
var aSpeaker = new Speaker('Joe');
var aListener = new Listener('Bobby');
aSpeaker.sayHi(aListener);
And by the way, you do not have private members in Javascript, only closures.
So yes, any function defined outside the scope of the 'private' member will
not be able to read/write to it.
Be advised also that, if performance is an issue, closures are slower on the
less performant js engine.
A not-so-bad solution to have 'pseudo-private' members is to define those members
as not enumerable with Object.defineProperty()
(watch here :
https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/defineProperty )
The order of execution is the one you write. There are only two exceptions from the rule "everything below is irrelevant": variable and function declarations are hoisted, i.e. you can use (assign to, call) them above. And beware of the difference between function declarations and function expressions.
var construct = new Constructor() //I can do this even if its above the declaration of the object.
Declaration of the constructor function you want to say.
construct.MyPrivilagedFunction(); //Can do this here too, even though it's above the function declaration.
There is no function declaration in here. The privileged method was created (with an assignment of a function expression to a property) during the execution of the constructor function (see above).
construct.MyPublicFunction(); //Can't do this because it is above the function declaration.
Again, it is no function declaration but an assignment of a function expression. And it didn't happen yet, because it is below.
This is only really a problem because I am working on a project where two objects will need to use each other's functions. If I place one object earlier in the code, it won't have access to the second object because prototyped functions adhere to the order of execution (top to bottom).
You usually don't need access to anything before you call anything. "Declare" everything at first (constructor, prototype properties), then instantiate.
var module = {};
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
function notGlobalFunction() {
console.log('I am global');
}
notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"
Can anyone help me understand what's going on here? I get that if you call notGlobalFunction(), it will just call the second function.
But what is var module = {} doing? and why is it called again inside the first function?
It says this is commonly known as a self-executing anonymous function but I don't really know what that means.
Immediately invoked functions are typically used to create a local function scope that is private and cannot be accessed from the outside world and can define it's own local symbols without affecting the outside world. It's often a good practice, but in this particular case, I don't see that it creates any benefit other than a few more lines of code because it isn't used for anything.
This piece of code:
(function(exports){
exports.notGlobalFunction = function() {
console.log('I am not global');
};
}(module));
Would be identical to a piece of code without the immediate invocation like this:
module.notGlobalFunction = function() {
console.log('I am not global');
};
The one thing that is different is that in the first, an alias for modules called exports is created which is local to the immediately invoked function block. But, then nothing unique is done with the alias and the code could just as well have used modules directly.
The variable modules is created to be a single global parent object that can then hold many other global variables as properties. This is often called a "namespace". This is generally a good design pattern because it minimizes the number of top-level global variables that might conflict with other pieces of code used in the same project/page.
So rather than make multiple top level variables like this:
var x, y, z;
One could make a single top level variable like this:
var modules = {};
And, then attach all the other globals to it as properties:
modules.x = 5;
modules.y = 10;
modules.z = 0;
This way, while there are still multiple global variables, there is only one top-level global that might conflict with other pieces of code.
Similarly, an immediately invoked function creates a local, private scope where variables can be created that are local to that scope and cannot interfere with other pieces of code:
(function() {
var x, y, z;
// variables x, y and z are available to any code inside this immediately invoked function
// and they act like global variables inside this function block and
// there values will persist for the lifetime of the program
// But, they are not truly global and will not interfere with any other global
// variables and cannot be accessed by code outside this block.
// They create both privacy and isolation, yet work just as well
})();
Passing an argument into the immediately invoked function is just a way to pass a value into the immediately invoked function's scope that will have it's own local symbol:
(function(exports) {
// creates a local symbol in this function block called exports
// that is assigned an initial value of module
})(module);
This creates a new empty object:
var module = {};
It does the same as:
var module = new Object();
This wrapper:
(function(exports){
...
}(module));
only accomplishes to add an alias for the variable module inside the function. As there is no local variables or functions inside that anonymous function, you could do the same without it:
module.notGlobalFunction = function() {
console.log('I am not global');
};
An anonymous function like that could for example be used to create a private variable:
(function(exports){
var s = 'I am not global';
exports.notGlobalFunction = function() {
console.log(s);
};
}(module));
Now the method notGlobalFunction added to the module object can access the variable s, but no other code can reach it.
The IIFE is adding a method to the module object that is being passed in as a parameter. The code is demonstrating that functions create scope. Methods with the same name are being added to a object and the the head object (window) of the browser.
"self-executing" might be misleading. It is an anonymous function expression, that is not assigned or or given as an argument to something, but that called. Read here on Immediately-Invoked Function Expression (IIFE).
what is var module = {} doing?
It initializes an empty object that is acting as a namespace.
why is it called again inside the fist function?
It is not "called", and not "inside" the first function. The object is given as an argument ("exports") to the IEFE, and inside there is a property assigned to it.
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() {}
What does it mean, to write JavaScript in your own name scope, apparently it avoids conflicts and conforms to W3C standards but I have no idea what it means or how it is done?
What I think you mean is namespacing. It means that you should contain your code in a namespace so that you won't pollute the global scope (well, you did pollute it with only one variable and that's about it). Every function and other stuff you intend to create will live in that namespace.
A simple namespace example, in object literal
var ns = {
foo : function(){...},
bar : function(){...}
}
You only declared one global, ns. The rest are stored in it and accessible via ns
ns.foo();
ns.bar();
Real life examples can be seen in JS frameworks. For example, we have jQuery and Underscore
//jQuery uses "jQuery" and "$" as namespaces and has "each()"
$.each();
//Underscore has "_" as a namespace and also has "each()"
_.each();
Although they have the same function names, but they live in separate namespaces. This avoids conflict, and helps you identify what belongs where.
It's a way to minimize the use of global variables (thus avoiding possible conflicts).
var myNS = {}; // Your namespace (an object) = a global var.
myNS.title = "Demo"; // Your variables come here as object properties.
myNS.date = "2012-05-21";
The object properties can be of any type: scalar types, arrays, objects, functions...
I guess it means writing functions in your own object, instead of writing global functions:
var myScope = (function() {
function privateFunction1() {...}
function privateFunction2() {...}
function a() {...}
function b() {...}
function c() {...}
return {a: a, b: b, c: c};
})();
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.