Function inside a function for scoping - javascript

I am confused about this code how is this working although it looks simple but i am not getting the point of its working
<script>
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2));
console.log(add10(2));
</script>

Try to understand how closure works in JavaScript, then you will be able to understand.
Closure can simply be defined as "In JavaScript, the inner function has the access to all the variables defined outside of that functions."
Try understanding the concepts before trying to understand the code.

the function makeAdder returns a function that already will have "x" set with what ever you passed into "makeAdder"
<script>
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
//at this point "add5" looks like this:
/*
function add5(y){
return 5 + y;
}
so if we do: add5(2) - we know why we see the result we do
*/
console.log(add5(2));
</script>

It's called Closure
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
If you refer a variable in a function, it first checks that variable in its scope (inside that function) and if not found, it looks into that the environment where is was defined/declared.
So when you call your outer function with some parameter, it returns a new function. Inner function on invocation return sum of x a variable in parent scope when it (function) was defined and y the parameter passed to innner function. So inner function will keep remember the value of x when it was defined.
e.g.
var add5 = makeAdder(5);
Now add5 is a funtion which when initialized, value of x in it's parent scope was 5, so whenever you will call add5(4), it will do x + y where x = 5 value when retruned function was defined and y = 4 the value passed to add5 function or returned function.
I hope that will explain but I would suggest to read more about Javascript Closures. I added one reference above.

Related

Can you explain the order of execution in the code mentioned below?

function makeMultiplier (multiplier){
var myFunc = function (x){
return multiplier * x;
}
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(makeMultiplier(3)(10));
Here, I don't understand why and how does the var multiplyBy3 variable acts as a reference to the myFunc function mentioned above
The return value of executing the function makeMultiplier is function myFunc. This is being assigned to variable multiplyBy3 . Hence it will act as a reference to myFunc function
Order of execution:
makeMultiplier is defined
makeMultiplier is called with arg 3 and returns a new function and that returned function is stored in a variable named multiplyBy3.
console log called with makeMultiplier is called with 3, returns a new function and it is called with argument 10
In JavaScript all the non primitive objects' assignments are stored as reference, but not as value. Example variable assignments, argument passing to functions where it basically assigned to the parameter which is a local variable inside the function.
However, second call to the multiplier with arg 3 is a different function, the references are different.
Also you can test those with Object.is() static method.
In your code, you don't actually use multiplyBy3, but here's your code modified to use it as the reference to the inner myFunc(3):
function makeMultiplier(multiplier) {
var myFunc = function(x) {
return multiplier * x;
}
return myFunc;
}
var multiplyBy3 = makeMultiplier(3);
console.log(multiplyBy3(10));
When setting the multiplyBy3 variable, we call the makeMultiplier function with 3 as our multiplier argument. This returns a reference to function(x) { return 3 * x; } which is assigned to multiplyBy3.
Calling multiplyBy3(10) then results in the value of 30 due to multiplying 3 by the argument of 10. This is equivalent to your original code makeMultiplier(3)(10)
In the following code snippet, I modified your code to use multiplyBy3 and threw in some console.log statements to show the steps taken both outside and inside the functions.
function makeMultiplier(multiplier) {
console.log("[enter] makeMultiplier");
var myFunc = function(x) {
console.log("[enter] myFunc");
return multiplier * x;
}
return myFunc;
}
console.log("[before] 'var multiplyBy3 = makeMultiplier(3);'");
var multiplyBy3 = makeMultiplier(3);
console.log("[after] 'var multiplyBy3 = makeMultiplier(3);'");
console.log("[before] 'console.log(multiplyBy3(10));'");
console.log(multiplyBy3(10));
console.log("[after] 'console.log(multiplyBy3(10));'");
Additionally, I'll show an alternate example where we multiply by 4:
function makeMultiplier(multiplier) {
console.log("[enter] makeMultiplier");
var myFunc = function(x) {
console.log("[enter] myFunc");
return multiplier * x;
}
return myFunc;
}
console.log("[before] 'var multiplyBy4 = makeMultiplier(4);'");
var multiplyBy4 = makeMultiplier(4);
console.log("[after] 'var multiplyBy4 = makeMultiplier(4);'");
console.log("[before] 'console.log(multiplyBy4(10));'");
console.log(multiplyBy4(10));
console.log("[after] 'console.log(multiplyBy4(10));'");

Passing a value to anonymous function as a function argument

y1 and year1 are undefined inside the anonymous function, which is a parameter to circle.attr(). However, 'year1' does have the right value before the code enters circle.attr(). Could someone explain why this is?
**I did get the function to work by replacing the 2nd parameter with "xYear(y)"
function circleLocation(y) {
year1 = y
console.log(year1)
circle.attr('cx', function(year1) {
y1 = year1;
console.log(y1)
console.log(year1)
return xYear(y);
})
}
You are redefining year1. Arguments of a function are like variables inside their scope. So this:
function (year1) {
// ...
Is more or less the same as: (has the same effect but it's not the same thing)
function() {
var year1;
// ...
The year1 variable is shadowing the other year1 (the one you want). Try this:
circle.attr('cx', function() { // without the argument year1
y1 = year1;
console.log(y1)
console.log(year1)
return xYear(y);
})
First off, it looks like you're introducing global variables so I'd suggest using var to prevent this from happening.
var year1 = y;
Next, it's hard to understand but I think you're confused about why year1 has a value before executing your anonymous function and why it's undefined inside of the anonymous function.
The problem here is that you're shadowing the other variable. Your anonymous function takes a parameter named year1
circle.attr('cx', function(year1) {
...
That means you have declared a variable named year1 inside of that functions scope. Whenever you declare a variable inside of a scope, that declaration will shadow the previous declaration. That means, it's a whole new variable and doesn't correlate with the previous one.
var x = 2;
function useGlobal() {
// No x is declared here so it grabs the next available x value
// which is the global one
console.log(x);
}
function hideX(x) {
// Here we've said that the function takes a parameter named x
// This means we can no longer access the outer variable named x
console.log(x); // undefined
}
function declareX() {
// Same thing as before, we've declared a new x so the old
// one is shadowed
var x = 500;
console.log(x);
}
useGlobal();
hideX();
declareX();
// Notice how declareX didn't change the original x
useGlobal();
you not have introduced a parameters in function circleLocation(args)
function circleLocation(y) {
year1 = y
console.log(year1)
attr('cx', function(year1) {
y1 = year1;
console.log(y1)
console.log(year1)
return xYear(y);
})
}
function attr(n,fun){
}
circleLocation(4);

Why is the function returned from a callback function not forming closure over the function where it is called?

I am having trouble in understanding the output from the below code (In Javascript) :
function outerFunction(callback){
var x =10;
var myCallbackRet = callback();
myCallbackRet();
}
outerFunction(function(){
return function(){
console.log(x); //output - x is not defined
}
});
As far as i understand when function myCallbackRet is called then [[Scope]] property of myCallbackRet is set to the Scope chain of the outerFunction and so the variable x should be accessible inside `myCallbackRet'.
Why is the output 'undefined'? Thanks a lot in advance.
Basically it has to do with where your function is defined. It was defined out of scope. Closure only works when a function is defined some where. Setting a variable to a function and calling it doesn't make everything above it available inside the function being called or there would be no reason to pass parameters to a function. Something like this would work.
function outerFunction(callback){
var x =10;
var myCallbackRet = callback();
myCallbackRet(x);
}
outerFunction(function(){
return function(y){
console.log(y);
}
});
Or this:
function outerFunction(callback){
var myCallbackRet = callback();
myCallbackRet();
}
outerFunction(function(){
var x =10;
return function(){
console.log(x);
}
});
Your anonymous function
function(){
return function(){
console.log(x)
is defined on the same scope (global) as outerFunction, but x is defined inside the scope outerFunction.
The scope of the function is set at the moment the function is defined, rather than at the moment when a function is assigned to variable.

Why is non-static variable behaving like static?

function emergency() {
var ambulance = 100;
var callAmbulance = function() { alert(ambulance); }
ambulance++;
return callAmbulance;
}
var accident = emergency();
accident(); // alerts 101
I am referring to the variable 'ambulance'.
When I call accident(); it should call emergency() which should use the declared variable 'ambulance' [considering the global scope thing in javascript, still it could set the value to global] but its using old value 101 instead of setting again back to 100 - behaving more like static var.
What's the Explanation?
What you have there is called a closure. It means a function can access variables declared in outer functions (or in the global scope). It retains access even after the 'parent' function has returned. What you need to understand is that you don't get a copy. The changes performed on that variable are visible to your inner function, which in theory means you could have multiple functions sharing access to the same variable.
function f () {
var x = 0;
function a() { x += 1; }
function b() { x += 2; }
function show() { console.log(x); }
return {a:a, b:b, show:show};
}
var funcs = f();
funcs.a();
funcs.b();
funcs.show(); // 3
One thing to be aware of is that a subsequent call to f will create a new scope. This means a new x variable will be created (new a, b, show functions will be created as well).
var newFuncs = f();
newFuncs.a();
newFuncs.show(); // 1
funcs.a();
funcs.show(); // 4
So, how do you get a copy? Create a new scope.
function g () {
var x = 0;
var a;
(function (myLocal) {
a = function () { myLocal += 1; }
}(x));
x += 200;
return a;
}
JS only has pass-by-value so when you call the anonymous function, the xvariable's value will be copied into the myLocal parameter. Since a will always use the myLocal variable, not x, you can be certain that changes performed on the x variable will not affect your a function.
If, by any chance, you're coming from a PHP background you are probably used to do something like
use (&$message)
to allow modifications to be reflected in your function. In JS, this is happening by default.
You are creating a function definition which is not compiled at this time:
var callAmbulance = function() { alert(ambulance); }
And before you are sending it to the called function, you are incrementing the num:
ambulance++;
And then you are sending it to the called function:
return callAmbulance;
But whether you are sending it there or not, it doesn't matter. The below statement executes or compiles the function:
var accident = emergency();
And this takes in the current ambulance value which is 101 after the increment. This is an expected behaviour in creating function but not executing it. Please let me know, if you didn't understand this behaviour. I will explain it more clearly.

Why does this alert 5?

Curious bit of code here...
var x = 5;
function fn() {
x = 10;
return;
function x() {}
}
fn();
alert(x);
Here's the jsFiddle
Is function x() {} called at all after return ?
Why not alert 10?
function x() {} is hoisted to the start of fn's scope, and this effectively makes x a local variable before x = 10; is evaluated.
The function is not set to 10.
Update: The sentence above is wrong. x is actually set to 10. var is not used to declare it, but even if it was, the last sentence in the quote below only refers to the declaration part of the name x, not its assignment to 10.
From MDN (emphasis mine):
function
Three forms with different scope behavior:
declared:
as a statement at the parent function top-level
behaves like a var binding that gets initialized to that function
initialization "hoists" to the very top of the parent function, above vars
var
function-scoped
hoist to the top of its function
redeclarations of the same name in the same scope are no-ops
function x float to the top, so you assigning the function to 10
You are declaring function x within fn; therefore, you are using the locally scoped version of x. It doesn't matter at what point the function x is declared. What you are actually doing when you set x to 10 is you are setting the function of x to 10.
This code also alerts 5:
var x = 5;
function fn() {
x = 10;
return;
var x;
}
fn();
alert(x);​
The important point is that you are declaring a local variable x. Declaring a variable after the return statement also doesn't matter - it is still a local variable.
Remove the declaration and you get 10 instead because the x is no longer a local variable.
This is caused by the way variable hoisting works in JavaScript. Variable declarations are hoisted but not their assignemnts. Function declarations are also hoisted together with the function body (although function expressions are not).
So your code is effectively doing this:
var x = 5;
function fn() {
var x;
x = function () {}
x = 10;
return;
}
fn();
alert(x);
The x within the function is hence declared with only local scope and does not affect the x decalred in the main code.
This is because fn is an object, and x is a property of that object. Local-scope always takes precisence over globals.
X in fn() is a function
but x in the global scope is a var
remove the function x() {} part and x will be alerted 10

Categories