I am looking at this function
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + (++tmp));
}
}
var bar = foo(2); // bar is now a closure.
bar(10);
when I run it, the variables get the following values
x = 2,
y = 10
tmp = 3.
Now I see that in foo(2) x is passed as 2. So its understandable that x is getting the value of 2. But then bar(10) is assigning a value of 0 to y. Hows that? I am confused on how does the receiving function know that 10 is the value for y assigned by bar(10)
foo(2) returns an anonymous function which accepts one parameter (y). As you're setting bar to be the return value of foo(2), bar becomes a reference to that anonymous function.
So, when you call bar(10) you're calling the anonymous function foo returns, and so 10 is being set to the parameter y.
This is a closure.
When you write:
var bar = foo(2);
it's actually calling foo, so the net result is:
var bar = function (y) {
alert(2 + y + (++tmp));
}
where tmp is the value bound in scope by the closure.
So, subsequently calling:
bar(10);
is passing 10 into that function, with the result being:
alert(2 + 10 + (++tmp));
tmp will increase each time you call any function created with foo
Related
console.log((function(x, f = () => x) {
var x;
var y = x;
x = 2;
return [x, y, f()];
})(1));
This is the code snippet. The output here is (3) [2, 1, 1]
How is the third output 1 and not 2?
Also, if I run this code on Scratch JS, it prints (3) [2, 1, 2]
Why is the output different here?
I tried passing a second argument in the IIFE function as in:
console.log((function(x, f = (z) => z) {
var x;
var y = x;
x = 2;
return [x, y, f(z)];
})(1, 2));
but this throws an error
Output is (3) [2, 1, 1] in chrome console, but (3) [2, 1, 2] in Scratch JS
How is the third output 1 and not 2? [...] Why is the output different here?
If the code is run as written, then the default parameter is evaluated before entering the function. So the x in f = () => x is referring to the first parameter of the function, not the var x defined inside of it. And since 1 was passed in to the IIFE, 1 is the value used.
Why is the output different here?
It appears that scratchJS is transpiling to an older version of javascript. This turns the code into something like this:
console.log(function (x) {
var f = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {
return x;
};
var x;
var y = x;
x = 2;
return [x, y, f()];
}(1));
Now the default value is handled by code inside the function body. Because of hoisting, var x is the variable that's referred to when doing return x, not the x in the argument list. By the time f is called, that local variable has been set to 2, so 2 is logged.
In the first case, () => x is returning 1 because you didn't pass a function as 2nd argument, that means the arrow function is instantiated outside of your function and keeps its own context. the x inside the function is confined to a different context.
This is a classic issue with shadowed name variables, same name but different nested context.
In the second example you are passing the value 2 as a function in your arguments, which is why it's throwing. You can't execute 2().
This question already has answers here:
Does JavaScript pass by reference? [duplicate]
(13 answers)
Closed 7 years ago.
Why doesn't this work and is there any way to get it to work?
Im pretty sure it doesn't work because of variable scoping in javascript, but I can't think of any ways to get it to work.
Code
var x = 5;
var z = function(y) { y = 10; };
z(x);
console.log(x) // Outputs 5 instead of 10
var x = 5
var z = function(y) { y = 10; }
console.log(x) // Outputs 5 instead of 10
Where exactly did you changed X? you dont have X and you did not call the function as well.
I assume you wish to do this:
var x = {x: 5}
var z = function(y) { y.x = 10; }
z(x);
console.log(x.x) // Outputs 10
The code is using x as variable on an object instead of a primitive number which is passed by value and not by reference and thus cannot be modified.
Using object you can modify the attributes (properties) of the object
X won't change for a couple reasons. The first is that you are modifying the parameter y inside of the function. If you passed an object this would work as those are passes by reference. It would also work if you changed x directly instead of passing it as an argument.
The second reason is that you never ran the function. You need to call z with z()
What happens when you invoke the function z is that the parameters get initialized and assigned the value you passed in.
So the function might read something like
var y = 5;
y = 10;
and so, the y that is in the scope outside of the function, remains unchanged because this y is actually a whole new y variable just for this function's scope.
var x = 5;
var z = function(y)
{
y = 10;
//assigned value 10 to the function parameter variable y.
//You haven't done x=y or x=10 and so how do you expect the value of x to change?
}
console.log(x) // Outputs 5 instead of 10
Change it to:
var x = 5 ;
var z = function(y)
{
x = 10; //changed value of x to 10
}
console.log(x) // Outputs 10
The problem is not related to vatiable scope at all.Your variable x is global since it is outside the function.
AND YES,you can change it's value inside a function.But the problem with your code was that you never changed the value of x.
If this is what you intended to do:
z(x); //x=5 is passed to the function z
function(y)
{
y=10; //initially the value of y is 5.Since you have passed x.
//Doing y=10 does not change the value of x because y is another variable.The value of x was copied to y and y is not x.
x=y;//You have assigned 10 to x
}
console.log(x); //outputs 10
Changing the value of the function parameter does not change the value of the variable whose value you passed to the function.You are actually passing the value of x to y that is you are passing 5 to y and not the variable itself.
You are not passing the variable reference.You are just passing the value.
i have a global variable x, which has the same name as that of the inner function
when i execute the test function it also executes the function which has same as that of the global variable, this function contains assigns value to the variable which has the same name as that of the function, now when in the next line it alerts the value of the x, it alerts 2, but when after the execution of the test function if you alert the x it still alerts 10... y?
eg
var x =10; //assigns value 10 to global variable x
function test(){
function x () {
x = 2; //assigns value x
alert(x); // x =2
}
x(); //calls x
}
test(); //call function test
but if you alert x, then it gives 10...
why like this;
and if you do like this
var y =10; //assign value 10 to y
function test(){
function x () {
y = 2; //assign value 2 to y
alert(y); //alerts y is 2
}
x(); //call the function x
}
test(); //call the test function
and if you check y then also it is 2..
what is the difference between the two.. I know the behaviour of the second one..
but have no idea about the first one...
A function declaration does two things:
It declares a new variable in the current scope (with the same name as the function). This is the same as var x.
It creates a function and assigns it to that variable. This is the same as x = function x () { ... } except it is hoisted.
In the first example, the function declaration for x creates a variable x in the scope of test so when you x = 2;, you are overwriting the pointer to the function in x with 2 while leaving the other variable x (which exists in the wider scope and holds the variable 10 alone).
This can be demonstrated:
var x = 10;
function test() {
function x() {
x = 2; //assigns value x
}
alert("x inside test before calling x(): " + x)
x(); //calls x
alert("x inside test after calling x(): " + x)
}
alert("x outside test before calling test(): " + x)
test()
alert("x outside test after calling test(): " + x)
In the second example, the function is called y, so it doesn't create a new x in the narrower scope and x = 2 touches the original x.
The function keyword is similar to var -- they both make the name they define into a local variable. So there are two x variables: one whose scope is outside the test function, the other whose scope is inside the function. Assigning to the inner x has no effect on the outer x.
In your second version, you don't have a var or function declaration for y inside the function, so it accesses the global variable.
For more information, see
What is the scope of variables in JavaScript?
I was reading the following topic How do JavaScript closures work? and found this code:
function foo(x) {
var tmp = 3;
return function (y) {
alert(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
alert(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);
The author commented:
As expected, each call to bar(10) will increment x.memb. What might
not be expected, is that x is simply referring to the same object as
the age variable! After a couple of calls to bar, age.memb will be 2!
I am confused why it will return 2 always. Can you explain me how it will come 2 always?
What's happening here is that: foo returns a function that, when called, increments the memb property of the object originally passed in to foo.
It would be clearer for that parameter object, age, to be a simple object; but the original author is perhaps having fun here, so passes in a new Number - which, as far a Javascript is concerned, is as valid an object as any.
So when bar is called, the memb property on that Number object is created/incremented.
The "internal value" of that number remains unchanged; it's always 2. But age.memb gets incremented by one each time. That's what the author means by:
After a couple of calls to bar, age.memb will be 2!
The 2 here refers to the value of memb after being incremented a couple of times (ie twice), it's not related to the value of the Number that age just happened to be at the start. Call bar again, and age.memb will be 3.
It will not "always" be 2.
Author says: "After a couple of calls to bar, age.memb will be 2" - and after 2 calls it will be "2".
After 4 calls it will be 4.
Just paste this to firebug console:
function foo(x) {
var tmp = 3;
return function (y) {
//console.log(x + y + tmp);
x.memb = x.memb ? x.memb + 1 : 1;
console.log(x.memb);
}
}
var age = new Number(2);
var bar = foo(age); // bar is now a closure referencing age.
bar(10);
bar(10);
bar(10);
bar(10);
console.log('result: ', age.memb) // result: 4
bar(10) has a reference to foo(2)
So each time you call bar(10). It will execute the inner function(closure) of foo which
is having parameter y as 10 and since bar has age reference as 2. So age will be 2 always if you call bar(10) and y will be 10 or so depending on value provide. Closure basically saves the reference to inner function even if the outer function is not there.
If I understand correctly you obtain some like a function pointer in bar. This points to the nameless function. This nameless function always receives the same input because foo is only called once i.e. x never changes. As a result there is no memory in the nameless function giving you the input value of x as a result always.
Here's the example code I'm struggling with:
function greaterThan(x) {
return function(y) {
return y > x;
};
}
var greaterThanTen = greaterThan(10);
show(greaterThanTen(9));
Is there a way to put it in math terms or follow the flow or something? I don't know why 10 is x and 9 is y.
In the line:
var greaterThanTen = greaterThan(10);
You are assinging the variable x to the value 10 and then you store the function in the greaterThanTen Variable to be called later. this means that:
greaterThanTen = function(y) {
return y > 10;
};
So when you do:
greaterThanTen(9); #y = 9
You are calling:
return 9 > 10;
This function doesn't call a function, it returns a function.
This code is creating a new unary function where the original binary (greater than) operator's right-hand operand is prebound to a specific value.
In lambda calculus this binding is known as currying.
In Javascript the binding happens because the supplied value of the parameter x in greaterThan is permanently retained in the scope of the inner function (or "closure") that is returned.
So, when you call:
var greaterThanTen = greaterThan(10);
what you now have is a new function (named greaterThanTen) which always compares its single parameter to the bound value of 10.
Hence:
greaterThanTen(9);
will return false.
Create greaterThan(10)
Create function:
function(y){return y > x}
return function.
So, when you call greaterThan(10), the function returns a function whose local variable x is set to 10.
var greaterThanTen = greaterThan(10) equals:
var greaterThanTen = function(y){return y > 10};
To finish, greaterThanTen(9) is called, which equals 9 > 10, which is false.
The only thing that greaterThan does is to set a value for x in
function(y) {return (y>x);}
and store the resulting function in a variable name, in this case greaterThanTen, now with the contents
function(y) {return (y>10);}
Calling greaterThanTen(9) is the same as looking at
function(y = 9) {return (y>10);}
which is the same as
function(y = 9) {return (9>10);}
which is false. Hence false is returned.
Edit:
Example of function that returns a function here: http://i.imgur.com/aiHSH.jpg (x and y is switched around in y>x)
Namaste
The greaterThanTen variable represents a function taking one argument and returning a boolean value whether this argument is greater then 10.