How does self contained function work in javascript? - javascript

var count = 0;
(function curse() {
console.log(++count);
curse();
})();
can anybody explain how does this function work? as you can see i have called the function inside of its declaration, then why it does not show any error while i called it before it finishes its declaration? and while i tried it in google console, it loops through to infinity. i don't know what really going on and how does this code execute itself, even though i know the self-executing function in javascript. I will be glad if somebody explains this code. thanks in advance

var count = 0;
(function curse() {
console.log(++count);
curse();
})();
This can be explained using a divide and conquer approach.
1.- Explanation for:
(function someFnc(){})()
When you declare a function, this will actually return a Function object which can be assigned to a variable:
var someFnc = function(){};
Afterwards, you can do something with this variable like to actually call the function like so:
someFnc();
In your case, instead of assigning the return value of the declaration to some variable, You're actually calling the function right away by doing this:
(function foo())();
Long story short, the latter will assure that the function gets called immediately after being declared.
2.- Explanation for function curse(){ console.log(++count); curse(); }
The ++count is simply summing 1 to the variable count and after that it gets printed in console.
Recursion
The second part of this code is the interesting part, is a function that calls itself, this notion is perfectly valid and is called 'Recursion'.
I'll explain recursion with an example using pseudocode:
Chain of events:
The function curse is called
The variable count is increased by 1
The variable is printed to console
The function curse is called
The variable count is increased by 1
The variable is printed to console
The function curse is called
The variable count is increased by 1
The variable is printed to console
and so on...
Hope it helps.

If you write:
()();
You create an IIFE: https://developer.mozilla.org/en-US/docs/Glossary/IIFE
In this case, JavaScript try to run the function, inside first brackets,
and compute result of this function,
and return this result, from function-expression.
If you write some expression in the first brackets, you'll got an error:
(1+2)(); //Uncaught TypeError: 3 is not a function
If you write:
(function(){ return 1+2; })(); //3
You'll get 3, as an int.
If you write:
var x = (function(){ return 1+2; })(); //3 returns and write in x;
console.log('x', x); //3
Next, thing, your function is named.
If you write:
(function curse() {})();
JavaScript try to return result of function curse();
The name of this function is available in scope of IIFE (inside first brackets).
If you write:
(function curse() { return 1+2; })();
curse(); //curse is not defined
So, curse() is available only in first brackets.
This function is recursive, and this not return the result:
function curse() {
console.log(++count);
curse();
}
So JavaScript can not return result, and continue to compute this infinity times;
If you write this, without console.log (this operation took some time):
var count = 0;
(function curse() {
curse();
})();
You'll got an error Uncaught RangeError: Maximum call stack size exceeded.
Inside your function, at line console.log(++count);,
JavaScript call console.log,
then get value of count variable
(it's available in scope of function curse,
because expression writted in the place, where count is available for this place),
then increment this value ++,
show result,
and save this in variable count.
With each call of the command console.log(++count);
count value is increasing,
but because there is no any end, this increasing infinity.
You can also, write the following code,
var count = 0;
(function curse() {
setTimeout(
function(){
console.log(++count);
curse();
},1000
)
})();
to reduce the computing power, and see how this working.

You have extra parentheses, which are not needed.
var count = 0;
function curse() {
console.log(++count);
if (curse < 100) {
curse();
}
}

Related

What does this extra set of parentheses do? [duplicate]

I'm a javascript newbie trying to wrap my mind around this code.
I got it here http://brackets.clementng.me/post/24150213014/example-of-a-javascript-closure-settimeout-inside
I still have a hard time understanding it. Since it involves some pattern I'm not familiar with.
// output 0-9, seperated by 1 sec delay.
for (var i = 0; i < 10; i++) {
setTimeout(function(x) {
return function() {
console.log(x);
};
}(i), 1000*i);
}
What is the meaning of (i) in this section of code?
function(x) {
return function() {
console.log(x);
};
}(i)
I thought it is an immediately invoked function expression.
But isn't the correct syntax for that is:
(function() {
// some code
})();
That is, indeed, an IIFE. The syntax you quote is an IIFE of 0 arguments; the syntax you asked about is an IIFE of 1 arguments. It will assign i to x in the inner code. Compare:
var print0 = function() {
console.log("Hello!");
};
print0();
is (in isolation) equivalent to
(function() {
console.log("Hello!");
})();
Thus the name: you create a function, then immediately invoke it.
However, if you want an argument, nothing really changes:
var print1 = function(name) {
console.log("Hello, " + name);
};
print1("George");
is (in isolation) equivalent to
(function(name) {
console.log("Hello, " + name);
})("George");
The parentheses here ensure that the function definition will be taken as an expression rather than as a statement. There are other ways to ensure that, a common one being
!function() {
console.log("Hello!");
}();
(But there are reasons to prefer the parentheses.) Since you are using it as an argument to the setTimeout call, it can't possibly be a statement, so these hacks are not necessary. It is still called "immediately invoked function expression", since you are still constructing a function expression and immediately invoking it.
The reason why an IIFE is used here is to "capture" the value of the variable i, rather than the location of x. Without the closure trick, you would get 10 timeouts, all outputting 10 (the value of the location denoted by x when the console.log resolves).
Yes it is, and the (i) is the argument list for the call. Have a look here for a detailed explanation. The grouping parenthesis are unncessary in this case, as it is an argument to the setTimeout function call and therefore an expression anyway.
The term IIFE does not only refer to the statement form of this pattern, where the parenthesis would be necessary.
The parantheses are optional in your example of an immediately invoked function.
(function() {
// some code
})();
Can be re-written as
function() {
// some code
}();
So the i in the example function's call becomes the x in the function definition.
function(x) { // x = 1
return function() {
console.log(x); // x = 1
};
}(1)

Attempting to generate HTML in vanilla JS using document.write, then access the tags using .getElementById [duplicate]

I need to run a javascript function each 10 seconds.
I understand the syntax must work like follow but I am not getting any success:
function funcName() {
alert("test");
}
var func = funcName();
var run = setInterval("func",10000)
But this isn't working. Any help?
A lot of other answers are focusing on a pattern that does work, but their explanations aren't really very thorough as to why your current code doesn't work.
Your code, for reference:
function funcName() {
alert("test");
}
var func = funcName();
var run = setInterval("func",10000)
Let's break this up into chunks. Your function funcName is fine. Note that when you call funcName (in other words, you run it) you will be alerting "test". But notice that funcName() -- the parentheses mean to "call" or "run" the function -- doesn't actually return a value. When a function doesn't have a return value, it defaults to a value known as undefined.
When you call a function, you append its argument list to the end in parentheses. When you don't have any arguments to pass the function, you just add empty parentheses, like funcName(). But when you want to refer to the function itself, and not call it, you don't need the parentheses because the parentheses indicate to run it.
So, when you say:
var func = funcName();
You are actually declaring a variable func that has a value of funcName(). But notice the parentheses. funcName() is actually the return value of funcName. As I said above, since funcName doesn't actually return any value, it defaults to undefined. So, in other words, your variable func actually will have the value undefined.
Then you have this line:
var run = setInterval("func",10000)
The function setInterval takes two arguments. The first is the function to be ran every so often, and the second is the number of milliseconds between each time the function is ran.
However, the first argument really should be a function, not a string. If it is a string, then the JavaScript engine will use eval on that string instead. So, in other words, your setInterval is running the following JavaScript code:
func
// 10 seconds later....
func
// and so on
However, func is just a variable (with the value undefined, but that's sort of irrelevant). So every ten seconds, the JS engine evaluates the variable func and returns undefined. But this doesn't really do anything. I mean, it technically is being evaluated every 10 seconds, but you're not going to see any effects from that.
The solution is to give setInterval a function to run instead of a string. So, in this case:
var run = setInterval(funcName, 10000);
Notice that I didn't give it func. This is because func is not a function in your code; it's the value undefined, because you assigned it funcName(). Like I said above, funcName() will call the function funcName and return the return value of the function. Since funcName doesn't return anything, this defaults to undefined. I know I've said that several times now, but it really is a very important concept: when you see funcName(), you should think "the return value of funcName". When you want to refer to a function itself, like a separate entity, you should leave off the parentheses so you don't call it: funcName.
So, another solution for your code would be:
var func = funcName;
var run = setInterval(func, 10000);
However, that's a bit redundant: why use func instead of funcName?
Or you can stay as true as possible to the original code by modifying two bits:
var func = funcName;
var run = setInterval("func()", 10000);
In this case, the JS engine will evaluate func() every ten seconds. In other words, it will alert "test" every ten seconds. However, as the famous phrase goes, eval is evil, so you should try to avoid it whenever possible.
Another twist on this code is to use an anonymous function. In other words, a function that doesn't have a name -- you just drop it in the code because you don't care what it's called.
setInterval(function () {
alert("test");
}, 10000);
In this case, since I don't care what the function is called, I just leave a generic, unnamed (anonymous) function there.
Change setInterval("func",10000) to either setInterval(funcName, 10000) or setInterval("funcName()",10000). The former is the recommended method.
That's because you should pass a function, not a string:
function funcName() {
alert("test");
}
setInterval(funcName, 10000);
Your code has two problems:
var func = funcName(); calls the function immediately and assigns the return value.
Just "func" is invalid even if you use the bad and deprecated eval-like syntax of setInterval. It would be setInterval("func()", 10000) to call the function eval-like.
Try this:
function funcName() {
alert("test");
}
var run = setInterval(funcName, 10000)
Btw this didn't work
setInterval(function () {
alert("test");
}, 10000);
I had to give a name (whatever you like) to the anonymous function:
setInterval(function alertNotification () {
alert("test");
}, 10000);

Javascript: Are callback functions the only ones allowed to refer to outside variables in a forward-looking way?

I have the following code, note that in the callback function for the close event, the reference to the variable ConnectingLine, which comes after the callback itself:
$('.tabs').tabs({
close: function(event, ui) {
ConnectingLine.show();
}
});
var ConnectingLine = MyHelpers.connectingLine({options here...});
I was assuming that this kind of referencing would work for any kind of closure, but it turns out to be not true. For example:
var add = (function () {
return function () {return counter += 1;}
var counter = 7;
})();
function myFunction(){
document.getElementById("demo").innerHTML = add();
}
The above code would break, causing a NaN error. Apparently, the definition needs to be before the closure function referring to it.
My question is, what allows the callback function to refer to outside variables in a forward-looking manner? Is this really unique to callback functions only? Thanks.
Control never reaches
var counter = 7;
Therefore your maths uses an undefined value (counter is declared and available for use because it is hoisted). The += operator coerces undefined to NaN and NaN is toxic.
Hence the result.

assign a function into a variable and run itself

I have read a interested blog where this above technique is applied, i understand it will run the function itself. but what's the purpose assign to a variable, when i try to console.log the variable i get undefiend.
var test1 = (function(){
console.log('yay')
})();
console.log(test1)
what's the differnet doing this way below
(function test1(){
console.log('yay');
})();
Suggestion are appreciated. :)
The immediately invoked function expression (IIFE) in Javascript serves to introduce a closure via a new scope. This is often done to compensate for the lack of block scoping in Javascript or provide information hiding a la module pattern (seen often in jQuery plugins).
Minimal example below:
var counter = (function() {
var i = 0;
function inc() {
i++;
return i;
}
return inc;
})();
The return exposes assigns the function inc to the variable counter. Successive invocations of counter() will result in 1, 2, etc. while keeping i hidden.
This is roughly equivalent to an object oriented approach that declared i as private.
In your sample above the function is void which makes no sense to assign the function result to a variable since it is returning nothing:
However tweaking your sample a little bit:
var test1 = (function(){
console.log('yay'); return "hello";
})();
then it makes sense since test1 will return "hello".
So in your original sample there are not differences and the fact that you assign a the result of a function which is not returning values is a bit odd.

JavaScript anonymous function expression vs IIFE

Encountered some code that's using IIFEs in an expression rather than just a normal function.
var custom_type = (function() {
return $('#myDiv').attr('custom_type');
})();
Normally I would write this as something like:
var custom_type = function() {
return $('#myDiv').attr('custom_type');
};
What's the reason for the IIFE? The only thing I can think of is that the IIFE might assign the custom_type variable only once at the beginning whereas the second might continue to check for the updated type every time the variable is referenced.
In this example, you can dispense with the function altogether and just do:
var custom_type = $('#myDiv').attr('custom_type');
However in general you can use an IIFE for more complex "just-in-time" computation of variable assignments - I like to use them if I need to iterate over something, so I can have i without polluting the current scope.
In your second example, though, the result is completely different - you will need to call the function custom_type() to get the current value, whereas the first piece of code will get its value once, and the variable will hold that value.
The IIFE will actually run (immediately-invoked function expression), so the variable will be set to its response.
Here's a JSFiddle to demonstrate this, watch your JS console for the output: http://jsfiddle.net/Y4JmT/1/
Code Here:
var custom_type = (function() {
return 'foo';
})();
var custom_type2 = function() {
return 'bar';
};
console.log('iife = ' + custom_type);
console.log('non-iife = ' + custom_type2);
In your JS console you'll see something similar to:
iife = foo
and
non-iife = function () {
return 'bar';
}
The first one of yours (IIFE) executes the function and store its result, the seconds stores function as definition.
(function(x) {
return x * 2;
})(5);
You are making a call like to normal funciton: func(arg1, arg2), but instead of function name you pass whole function definition, so the above would return 10 like:
function multiply(x) {
return x * 2;
}
multiply(5);
They mean the same thing, you are making calls. Unlikely the first, second is definition plus a call.
IIFEs allow you to invoke a function (anonymous or otherwise) at the point of creation.
Have you looked at this?
http://benalman.com/news/2010/11/immediately-invoked-function-expression/

Categories

Resources