Lexical scoping in JavaScript - javascript

Why is 100 being logged here instead of 101?
function myFunction() {
var i=100;
function f() {
return i++;
}
return f();
};
var X = myFunction();
console.log(X);
http://jsfiddle.net/PhillipSenn/8fqyh/

Because f() returns the value of i before it is incremented. Use pre-increment (++i) if you want the value after it is incremented.
Also, it's a bit odd to declare f() for no other purpose than to immediately call it. I think what you intended was to return a function that increments i and returns the new value each time it is called. To achieve this, simply return the function, then call console.log(X()) to invoke f() and log the incremented value:
function myFunction() {
var i=100;
return function() { return i++; }
};
var X = myFunction();
console.log(X());

Related

Why do immediately invoked function and non-immediately invoked function behave differently when running return statement?

I've encountered an instance of a difference between immediate invocation and non-immediate invocation of a function:
var x = (function foo() {
return function() {
console.log('something');
}
})();
x();
// logs 'something'
var x = function foo() {
return function() {
console.log('something');
}
};
x();
x();
// no log at all
Why is there a difference here?
In all other cases, as far as I know, immediately and non-immediately invoked functions behave exactly the same.
I didn't find any documentation on this issue.
They don't behave differently in the sense that an IIFE is just a regular function call.
However in the first case, x refers to the result of the outer function being called, which is the inner function, while in the second case x refers to the outer function. Therefore in the second case you call the outer function twice, and the inner function gets returned, but you ignore that returned value. Do:
var inner = x();
inner(); // tadaa
var x = (function foo() {
return function() {
console.log('something');
}
})();
x();
// logs 'something'
First version immediately executes the function which returns another function which is stored at variable x. Then calling x() actually executes the internal function and somethign is logged.
var x = function foo() {
return function() {
console.log('something');
}
};
x();
x();
// no log at all
Second version simply stores to variable x the external function. When calling x() it simply returns the internal function. Since that internal function is not stored or accessed anywhere, it is not called, hence nothing is logged.
What you could do (for second version):
y = x();
y(); // now logs something
// or equivalently
x()(); // now logs something
When you execute the second function expression, the expression is simply returning a reference to the inner function which is supposed to print something in the console. In other words, when x is executed it is not executing the returned function expression:
function() {
console.log('something');
}
To do that you need to execute the returned expression by placing another pair of parenthesis ():
// x now has a reference to the outer function
var x = function foo() {
return function() {
console.log('something');
}
};
//y has a reference to the inner function, as outer function has returned a ref to it
var y = x();
// To print in console, just execute the inner function
y();
In the case of IIFE, you already have the reference of the inner function when you invoke the IIFE:
//x now has a reference to the inner function
var x = (function foo() {
return function() {
console.log('something');
}
})();
// you execute the inner function and print something in console
x();
in case 2 you are just setting x to equal a function that returns a NON invoked function you would need to invoke that function as well with x()()

Advantages of using inner functions(javascript)

this might not be a very specific question but I was wondering what are the advantages of using an inner function? I've recently started reading on closures (javascript) and they always refer to inner functions.
var pet = function(name) {
var getName = function() {
return name;
}
return getName;
}
myPet = pet('Vivie');
myPet();
Why would we not want to seperate the getName function and introduce a 'name' parameter so that we could call it independantly?
var pet = function(name){
return getName();
}
function getName(name){
return name;
}
Thank you, I am quite new to javascript
Try this article. Simple guide to understand closure in JavaScript
I copied here a part of the code explained in the article.
Run this code snippet to see the behavior of the inner function.
<script>
function outer() {
var b = 10;
var c = 100;
function inner() {
var a = 20;
console.log("a= " + a + " b= " + b);
a++;
b++;
}
return inner;
}
var X = outer(); // outer() invoked the first time
var Y = outer(); // outer() invoked the second time
//end of outer() function executions
X(); // X() invoked the first time
X(); // X() invoked the second time
X(); // X() invoked the third time
Y(); // Y() invoked the first time
</script>

Javascript let hoisting to the scope or creating where it is?

x declared after fn function but returns its value.
Why fn didn't return undefined?
function doWork(){
let fn = function(){ return x; }
let x = 2;
return fn();
}
console.log(doWork()); // 2
Inside of your doWork() function, first you set up a function and assign it to fn -- This function is not invoked yet. You then define x as 2. After this definition you invoke fn() by calling return fn().
Because JavaScript works from top-to-bottom, x is defined at the time you reference fn(), so fn() is able to return x correctly.
This can be seen in the following:
function doWork() {
let fn = function() {
return x;
}
let x = 2;
return fn();
}
console.log(doWork()); // 2

Execution order of simple function

I am a bit new to javascript, i was just trying the below snippet:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 2
I was under the impression that i would have to do s() to get 1 as the result and i was thinking that _getUniqueID() returns a function rather than execute the funtion inside it. Can somebody explain the exact execution of this function please ?
What you're seeing here is a combination of Javascript's notion of closure combined with the pattern of an immediately invoked function expression.
I'll try to illustrate what's happening as briefly as possible:
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}()); <-- The () after the closing } invokes this function immediately.
_getUniqueID is assigned the return value of this immediately invoked function expression. What gets returned from the IIFE is a function with a closure that includes that variable i. i becomes something like a private field owned by the function that returns i++ whenever it's invoked.
s = _getUniqueID();
Here the returned function (the one with the body return i++;) gets invoked and s is assigned the return value of 1.
Hope that helps. If you're new to Javascript, you should read the book "Javascript, the Good Parts". It will explain all of this in more detail.
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
s = _getUniqueID();
console.log(s); // 1
console.log(_getUniqueID()); // 1
when you do () it calls the function,
a- makes function recognize i as global for this function.
b- assigns function to _getUniqueID
you do s = _getUniqueID();,
a - it assigns s with return value of function in _getUniqueID that is 1 and makes i as 2
when you do _getUniqueID() again it will call the return function again
a- return 2 as the value and
b makes value of i as 3.
This is a pattern used in Javascript to encapsulate variables. The following functions equivalently:
var i = 1;
function increment() {
return i ++;
}
function getUniqueId() {
return increment();
}
But to avoid polluting the global scope with 3 names (i, increment and getUniqueId), you need to understand the following steps to refactor the above. What happens first is that the increment() function is declared locally, so it can make use of the local scope of the getUniqueId() function:
function getUniqueId() {
var i = 0;
var increment = function() {
return i ++;
};
return increment();
}
Now the increment function can be anonymized:
function getUniqueId() {
var i = 0;
return function() {
return i ++;
}();
}
Now the outer function declaration is rewritten as a local variable declaration, which, again, avoids polluting the global scope:
var getUniqueId = function() {
var i = 0;
return (function() {
return i ++;
})();
}
You need the parentheses to have the function declaration act as an inline expression the call operator (() can operate on.
As the execution order of the inner and the outer function now no longer make a difference (i.e. getting the inner generator function and calling it, or generate the number and returning that) you can rewrite the above as
var getUniqueId = (function() {
var i = 0;
return function() {
return i ++;
};
})();
The pattern is more or less modeled after Crockford's private pattern
_getUniqueID = (function () {
var i = 1;
return function () {
return i++;
};
}());
console.log(_getUniqueID()); // 1 , this surprised me initially , I was expecting a function definition to be printed or rather _getUniqueID()() to be called in this fashion for 1 to be printed
So the above snippet of code was really confusing me because I was't understanding that the above script works in the following manner, by the time the IFFE executes _getUniqueID is essentially just the following:
_getUniqueID = function () {
i = 1
return i++;
};
and hence,
_getUniqueID() // prints 1.
prints 1.
Note: please note that I understand how closures and IFFE's work.

how to use function(1)(2) in javascript? and how does it work?

I understand calling function(1) but not function(1)(2), how does it work?
also possible for function(1)(2)(3)(4) too?
In this case you are supposing that function(1) returns a function, than you are calling this new, anonymous function with an argument of 2.
See this example:
function sum(a) {
return function(b) {
return a+b;
}
}
// Usage:
window.alert(sum(5)(3)); // shows 8
var add2 = sum(2);
window.alert(add2(5)); // shows 7
window.alert(typeof(add2)); // shows 'function'
Here we create a function sum that takes one argument. Inside the function sum, we create an anonymous function that takes another argument. This anonymous function is returned as the result of executing sum.
Note that this anonymous function is a great example of what we call closure. A closure is a function that keeps the context in which it was created. In this case, it will keep the value of the variable a inside it, as did the example function add2. If we create many closures, they are independent as you can see:
var add3 = sum(3);
var add4 = sum(4);
window.alert(add3(3)); // shows 6
window.alert(add4(3)); // shows 7
Furthermore, they won't get "confused" if you have similarly named local variables:
var a = "Hello, world";
function multiply(a) {
return function(b) {
return a * b;
}
}
window.alert(multiply(6)(7)); // shows 42
var twoTimes = multiply(2);
window.alert(typeof(twoTimes));
window.alert(twoTimes(5));
So, after a call to sum(2) or multiply(2) the result is not a number, nor a string, but is a function. This is a characteristic of functional languages -- languages in which functions can be passed as parameters and returned as results of other functions.
You have a function that returns a function:
function f(n) {
return function(x) {
return n + x;
};
}
When you call f(1) you get a reference to a function back. You can either store the reference in a variable and call it:
var fx = f(1);
var result = fx(2);
Or you can call it directly:
var result = f(1)(2);
To get a function that returns a function that returns a function that returns a function, you just have to repeat the process:
function f(n) {
return function(x) {
return function(y) {
return function(z) {
return n + x + y + z;
}
}
};
}
If your function returns a function, you can call that too.
x = f(1)(2)
is equivalent to:
f2 = f(1)
x = f2(2)
The parenthesis indicate invocation of a function (you "call" it). If you have
<anything>()
It means that the value of anything is a callable value. Imagine the following function:
function add(n1) {
return function add_second(n2) {
return n1+n2
}
}
You can then invoke it as add(1)(2) which would equal 3. You can naturally extend this as much as you want.

Categories