I found some JavaScript syntax which is unknown for me and I even don't know how it's called or what it does so I can't find any documentation.
I found it on MDC Doc Center:
var Counter = (function() {
var privateCounter = 0;
function changeBy(val) {
privateCounter += val;
}
return {
increment: function() {
changeBy(1);
},
decrement: function() {
changeBy(-1);
},
value: function() {
return privateCounter;
}
}
})();
The part I am interested in is:
var Counter = (function() {})();
What the round brackets do? How this is called and where it can be used?
(function() {})() is an immediately executed function.
This creates private scope around a block of code. This also can create a closure which can be useful to maintain state after the function ends.
You require () around function() {} because function() {}() is an illegal statement (the JS parser fails).
Also it is a habit to make sure you wrap an immediately executed function in () so that readers of your code are aware they should be interested in the return value of the function instead of the function.
It's the module pattern. It's usually used to create singletons. See this answer:
What is this design pattern known as in JavaScript?
Consider when you have a function called a:
function a() {
alert("hi");
}
You call it like this:
a();
In (function() {})() you're just skipping the part where you defined the function before-hand. In one fell swoop, you've defined an unnamed function and called it.
Related
Function express CANNOT be used before being declared correct? But is also passed in a keypress function as well. How is this magic happening?
I am doing a code along and noticed it while I was looking over it.
var controller = (function(budgetCtrl, UICtrl){
var setUpEventListeners = function(){
//CTRLADDITEM is called below
document.querySelector(DOM.inputBtn).addEventListener('click', **ctrlAddItem**);
document.addEventListener('keypress', function(e){
if(event.keyCode === 13 || event.which === 13){
**ctrlAddItem();**
}
});
}
var **ctrlAddItem** = function(){
updateBudget();
}
};
}
})(budgetController, UIController );
This is called IIFE (Immediately Invoked Function Expression) and it's fairly common in Javascript as well as other languages like Go. Here is a simple version...
(function() {
alert('invoked immediately');
})();
This code will run immediately. Note: it is not invoked before it is defined. It is invoked by the trailing parenthesis, which come directly after it is defined. It is the exact same thing as doing this...
function doSomething() {
}
doSomething();
We have just inlined the function by wrapping it in parenthesis and then called it (), instead of calling it by name.
If you assign the result to a variable, it works just as expected, you are assigning the result of the function.
// these two are equivalent
var result = (function () {
return 5;
})();
var result = 5;
Now, the value in result will equal 5.
Why do we use them?
Most commonly, we use them to isolate the scope of your code to prevent it from polluting the global scope. For example, if this is your application code...
function MyApp() {
}
You have now polluted the global scope by creating window.MyApp. If you use a third party library that also provides a function on the global scope called MyApp, it will override yours. To prevent that, we can do...
(function(window) {
function MyApp() {}
MyApp();
})(window);
Now, MyApp is not attached to the window and we still have access to the window.
Further down the rabbit hole
You must convert your function from a declaration to an expression before you can invoke it immediately. To do this, you wrap it in parenthesis.
This does NOT work
function (){
// do something
}()
This DOES work (thanks to the parenthesis)
(function () {
})()
You can also use any unary operator instead of parenthesis. All of these work
~function () {
}()
+function () {
}()
-function () {
}()
void function () {
}()
What you have is:
// Pass ctrlAddItem
document.querySelector(DOM.inputBtn).addEventListener('click', ctrlAddItem);
// Include closure to ctrlAddItem in function expression
document.addEventListener('keypress', function(e){
if(event.keyCode === 13 || event.which === 13){
ctrlAddItem();
}
});
// later...
var ctrlAddItem = function(){ /* whatever */ }
So ctrlAddItem is declared, and therefore exists with a value of undefined before any code is executed. At the point it's used in addEventListener, its value is still undefined.
However, before the outer function completes (and before the listeners are called), ctrlAddItem is assigned a value. So by the time the listeners are called, it's a (reference to a) function.
I am working on angularJs and working on javascript optimization.
I recently saw a video by YUI creator who is a javascript expert about javascript optimization. He explained about variable declaration and scopes and how javascript work. and How javascript engine has to look for variable from current scope till global scope to find it etc etc (Ref: http://jonraasch.com/blog/10-javascript-performance-boosting-tips-from-nicholas-zakas)
My question regarding is (not specific to angularjs) is:
when in my controller i declare a function like:
app.controller('Ctrl', function() {
var func1 = function() {
console.log("Hello");
}
this.func2 = function() {
console.log("World");
}
func1();
this.func2();
});
Which function should be faster ? I know its a overkill but I am interested in knowing how javascript engine works.
in terms of scope these two are identical (they are both local, not global). the difference is in functionality: the "this.func2" function is "public" (you could call that function with a reference to an instance of the Ctrl object), where as the "var func1" is a "private" function.
in terms of the speed of executing a call, I have put together this small test on jspref:
http://jsperf.com/private-vs-public-speed-js
Benchmark.prototype.setup = function() {
var obj = (function() {
this.f1 = function() {
console.log('a');
}
var f2 = function() {
console.log('a')
}
return {
f1: f1,
f2: f2
}
})();
};
comparing between "use public method"
obj.f1();
to
"use private method"
obj.f2(); does not seem to show a significant difference most of the time.
En example can be found in Twitter'a typeahead.js here:
function () {
// ...
return this.each(initialize);
function initialize() {
// ...
}
}
Questions:
What are the scopes and what function sees what?
What is the reason for using such a construct (usage scenarios and advantages)?
Javascript has function based scope, which means that every thing defined inside a function is available from the first line, since the definition is "hoisted" by the complier.
That goes for both variable and function definitions - variable values however, are not available until after assignment.
You can read all about javascript scoping and hoisting here
This means that the function initialize is available from the first line of the wrapping anonymous function.
There is no real reason, and no advantages, for doing it that way, unless you count the code structure as an advantage.
Personally I don't see any reason to do this. For me even it looks a little bit weird. Martin is right. You should be careful, because the defined variables are not accessible like functions. For example this doesn't work:
var getValue = function(func) {
return func();
}
var f = function() {
return getValue(now);
var now = function() {
return 10;
}
}
alert(f());
However, this works:
var getValue = function(func) {
return func();
}
var f = function() {
return getValue(now);
function now() {
return 10;
}
}
alert(f());
In the module pattern in JavaScript "Immediately-Invoked Function Expressions" (also known as self-executing anonymous functions) are used as self executing functions that return an object.
How can a self-executing function hide private variables and only expose the returned object. Why does this not happen with a normal JavaScript function?
So in the following mini module, why could we not achieve the same concept of encapsulation without the enclosing ()()?
var Module = (function () {
var privateVariable = "foo",
privateMethod = function () {
alert('private method');
};
return {
PublicMethod: function () {
alert(privateVariable);
privateMethod();
}
};
})();
How can a self-executing function hide private variables and only expose the returned object. Why does this not happen with a normal JavaScript function?
It does happen with normal JavaScript functions.
function MakeModule() {
var privateVariable = "foo",
privateMethod = function () {
alert('private method');
};
return {
PublicMethod: function () {
alert(privateVariable);
privateMethod();
}
};
}
var Module = MakeModule();
would work just fine.
The only difference is that the anonymous function introduces one less global variable and allows for itself to be garbage collected while MakeModule can't be collected unless explicitly deleted by the author.
The privateness is because of closures. The "var privateVariable" is closed over by "PublicMethod", so only that function can access the variable because only it has it in its closure. It cannot be referenced by anything else and is "private"
This happens not only in "Immediately-Invoked Function Expressions" but also in normal function calls. It is just a way to immediately create the closure when defining the module instead of doing it later when you call the outer function.
Also see this post from Douglas Crockford himself: http://javascript.crockford.com/private.html
You can define a anonymous function via named function.
Example:
//factorial
(function(n){
var self = function(n){
//call self
return n > 0 ? (self(n-1) * n) : 1;
}
return self;
})()
What is the different between two declarations of a module in JavaScript?
One has parentheses around the function and other one doesn't?
One article says that
Notice the () around the anonymous function. This is required by the
language, since statements that begin with the token function are
always considered to be function declarations. Including () creates a
function expression instead.
Both seem to do the same thing when checked.
var person = (function () {
// Private
var name = "Robert";
return {
getName: function() {
return name;
},
setName: function(newName) {
name = newName;
}
};
}());
var person = function () {
// Private
var name = "Robert";
return {
getName: function() {
return name;
},
setName: function(newName) {
name = newName;
}
};
}();
Functions are of two types in JavaScript - declarations and expressions.
This is the difference between the two:
Function declarations are hoisted. This means you can call the function before it appears in the program as declarations in JavaScript are hoisted.
Function expressions can be invoked immediately. A function declaration cannot. This is because expressions express (or return a value). Function expressions express a function.
An example of a function declaration:
foo("bar");
function foo(bar) {
alert("foo" + bar);
}
The above program will work because foo is a function declaration.
foo("bar"); // throws an error, foo is undefined - not a function
var foo = function (bar) {
alert("foo" + bar);
};
The above program will not work as foo is declared as undefined, hoisted and then later assigned the value of a function expression. Hence it's undefined when it's called.
An example of a function expression:
(function (bar) {
alert("foo" + bar);
}("bar"));
The above function will be immediately invoked as it's a function expression.
function (bar) {
alert("foo" + bar);
}("bar"); // throws an error, can't call undefined
The above function will not be immediately invoked as it's a function declaration. Remember, declarations do not express (or return a value). So it's like trying to invoke undefined as a function.
How does a function become an expression?
If a function is used in the context where an expression is expected then it's treated as an expression. Otherwise it's treated as a declaration.
Expressions are expected when:
You're assigning a value to a variable (i.e. identifier = expression).
Inside parentheses (i.e. ( expression )).
As an operand of an operator (i.e. operator expression).
Hence the following are all function expressions:
var foo = function () {};
(function () {});
~function () {};
Everything else is a function declaration. In short if your function is not preceded by anything, it's a declaration.
See this code: https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94
The following function isExpression is used to test whether some arbitrary JavaScript code is an expression or not:
function isExpression(code) {
if (/^\s*function\s/.test(code)) return false;
try {
Function("return " + code);
return true;
} catch (error) {
return false;
}
}
Hope this clears any doubts in your mind.
In short:
A function expression expresses or returns a value (in this case a function). Hence it can be immediately invoked, but it can't be called before it appears in the program.
A function declaration is hoisted. Hence it can be called before it appears in the program. However since it doesn't express any value it can't be immediately invoked.
In the current context there's no difference for the interpreter. Usually preferable way of writing module is by wrapping the function with parentheses:
var person = (function () {
// Private
var name = "Robert";
return {
getName : function () {
return name;
}
};
}());
That's because the syntax is cleaner and it's obviously that you want to invoke the function immediately after it is declared. One more reason is because:
(function () {
//some stuff
}());
will work but
function () {
//some stuff
}();
this wont.
By wrapping the function each time you use common codding style which is usually a good thing :-).
The difference is that when writing:
var foo = (function () {
...
}());
the use of the (superfluous but useful) grouping () is a common coding style to make it clear from very like first line that the right hand side is most likely an immediately invoked function expression (IIFE). However, in the second:
var foo = function () {
...
}();
it doesn't become apparent until you read the last line, which might be quite a few lines down. Until you reach the last line, you probably thought you were reading a plain assignment:
var foo = function () {
...
};
Note that the parenthesis can be used in a plain assignment too:
var foo = (function () {
...
});
but in that case they really are superfluous (and probably misleading due to the convention of using them for IIFEs).
See An Important Pair of Parens.