How does greaterThanTen(9) become the y variable in the return function? What I mean is how does the parameter (9) become the y in the return function argument? Wouldn't 9 be replaced with x since greaterThanTen = greaterThan(10)? Wouldn't the 9 just replace the x = 10 parameter? I just don't understand how that 9 parameter is getting to y in the return function.
function greaterThan(x) {
return function(y) {
return y > x;
};
}
var greaterThanTen = greaterThan(10);
show(greaterThanTen(9));
It doesn't "become the y variable". The function greaterThan returns a function, and the value passed to greaterThan is "captured" in that returned function.
In other words, greaterThan(10) creates the following function:
function(y) { return y > 10; }
It's similar to writing:
function greaterThan10(y) { return y > 10; }
Functions that create functions take advantage of closures ("the thing that 'captures' the 10).
The advantage is that you don't need to keep writing greaterThanNnn functions for every number you want to use, you just call greaterThan(n) for whatever you need. This is a contrived, but popular, example, of course.
For chunks of info relating to referencing functions, when to use () and when not to, and some more realistic examples, see also:
Difference between calling function and referencing function?
When do I use parenthesis and when do I not?
Why function statement requires a name?
when you called greaterThan(10) it assigned value of x and return the function in greaterThanTen variable which now becomes
var greaterThanTen = function(x){10>x};
then in next line you called greaterThanTen(9) so it will assign the x value. i hope you understood what i said.
You must have to know the basis about the closures concept in JavaScript. Closures are the most tricky and special addition to the JavaScript language. As you will notice they follow the lexical scope of the language flow. Here in this example;
function greaterThan(x) {
return function(y) {
return y > x;
};
}
var greaterThanTen = greaterThan(10);
console.log(greaterThanTen(9));
If you see there is the main concept of closures. Once you call the function greaterThan it creates another function. But as you pass the first argument 10, it takes the place of x. Further when you call the function and pass the second argument 9
it takes place on y the function built inside. In this way the values are stored in the function call stack and you can compare and operate on those values.
Related
In the simple, 2 layer currying example below the word dog is passed into the y argument.
"use strict";
function layer2(x) {
return function(y) {
return console.log(x, y);
}
}
var layer1 = layer2('cat');
layer1('dog');
I know it works this way and I can reliably reproduce this. However I can't understand the mechanics of why this works. If I made a 100 layer example layer 1 would be the innermost function and the pattern would work outwards from that point. What piece of basic mechanics causes this? Thanks so much for any input!
In short, lexical scoping is what makes this possible. See, layer2 function in your example returns another function that has two variables in its scope:
y - its own argument
x - parameter passed into `layer2` function
The key point here is that once you store that returned function, x value is set and will never change. Again, in terms of your example, function stored in layer1 variable - result of layer2('cat') - has x name bound to 'cat' string value.
It's simple. When you call layer2('cat') it will return the function:
function(y) {
return console.log(x, y);
}
Now, layer1('dog') returns function call return console.log(x,y); on which x is received already in a call layer2('cat'), and y is being called from function(y).
Here's a very good read blog https://javascriptweblog.wordpress.com/2010/10/25/understanding-javascript-closures/ which will help you further.
In my attempt to understand a very specific aspect of closure in javascript, I felt compelled to illustrate it with an example. This is pulled from MDN's explanation of closure:
function makeAdder(x) {
return function(y) {
return x + y;
};
}
var add5 = makeAdder(5);
var add10 = makeAdder(10);
console.log(add5(2)); // 7
console.log(add10(2)); // 12
And this example is touched upon here, but I don't think it resolves my own personal confusion, although my confusion is also related to the value of y.
My question is when add5(2) returns function(y), how does it determine the value of y when y is not explicitly assigned anywhere within or outside of makeAdder(x)? Also, is add5(2) = makeAdder(5)(2)? And if so, how can this function execute when makeAdder(x)(y) is not defined in this example? Also, is there a way that describing it as such might help clarify this issue for someone who's having a hard time internalizing the logic behind closure? It appears as if add5(2) assigns 2 to y, but there's no clear way for me to trace this. Any help is much appreciated. Thank you!
One way to look at this is that
var add5 = makeAdder(5);
var add10 = makeAdder(10);
is essentially equivalent to
var add5 = function(y) {
return 5 + y;
}
var add10 = function(y) {
return 10 + y;
}
Perhaps this helps?
The variable "y" is the parameter of the function returned by a call to "makeAdder". It's value is not set in "makeAdder" because that wouldn't make sense; the whole point is to create a new function that will add a given value ("x") to a parameter ("y").
The returned function takes one argument, "y". When, after calling "makeAdder", code calls the function returned and so passes in a value for "y", the final addition (5 + 2 or whatever) is carried out.
Function call syntax (the parenthesized argument list) is evaluated left-to-right, so
makeAdder(5)(2)
is the same as
(makeAdder(5))(2)
meaning,
call the 'makeAdder' function with the parameter 5, and then when that returns treat its return value as a function reference and call that function with the parameter 2.
My question is when add5(2) returns function(y), how does it determine the value of y when y is not explicitly assigned anywhere within or outside of makeAdder(x)?
The function returned by makeAdder is:
function(y) {
return x + y;
}
where x has already been assigned the value 5.
So there is your y. It's inclusion as a formal parameter in the function expression is effectively the same as declaring it with var, x is initialised the same way in makeAdder.
Also, is add5(2) = makeAdder(5)(2)?
Yes, though I think you meant == (equals), not = (assignment).
And if so, how can this function execute when makeAdder(x)(y) is not defined in this example?
makeAdder returns a function, so the second set of parenthesis causes it to be called with whatever value is provided (including none):
makeAdder(5)(2) // 7
is the same as:
var foo = makeAdder(5);
var bar = foo(2);
the only difference being that in the second case, the intermediate result is stored as foo before being called.
Also, is there a way that describing it as such might help clarify this issue for someone who's having a hard time internalizing the logic behind closure?
The real power of a closure is that a function can return another function that continues to have the same scope chain it had when it was created, so that it has exclusive access to local variables of all the execution contexts on its scope chain (other than global variables, they aren't exclusive) after those functions have finished executing. Complex inheritance structures can be created with closures (not recommended though).
It's this persistence that makes a closures really useful, and not just scope chain resolution.
I'm new to Javascript, I'm self-teaching, so this might be an obvious area, but no matter how I phrase the question I can't really seem to get my head around this one issue. At the moment I'm reading through http://eloquentjavascript.net/chapter6.html (which was on mozilla's MDN). I've come across this a couple of times now, I would just like a simple break down if possible.
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
show(isNotNaN(NaN));
I don't understand how at the very last step isNotNaN (a variable) is passing an 'extra argument' (NaN) to the function stored in isNotNaN (negate(isNaN). "show(isNotNaN(NaN));"
I came across this same problem when the concept of enclosure was trying to be explained. But I don't get where this argument "NaN" is going in the above function, as it seems to me like the last statement ends up something like:
show(negate(isNaN, NaN));
I would be happy to provide more details. This concept of passing an extra argument to a variable already holding a function with an argument confuses the hell out of me!
There's no "extra" argument. The negate() function itself returns a function defined as a function expression, which can then be called with any number of original (not extra) arguments passed. A closure is used for the returned function to keep a reference to isNaN as func.
var isNotNaN = negate(isNaN);
At this point, isNotNaN contains a reference to the function
function(x) {
return !func(x);
};
Again, func here refers to the isNaN argument passed to the negate function, which is the immediate parent in the scope chain. The result is similar, but not the same as
var isNotNaN = function (x) {
return !isNaN(x);
};
The reason it is not the same is, if we change the value of isNaN, the behaviour of this function will change. In the example you posted, however, the value of func is equal to the original value of isNaN and cannot be changed by anything outside of its scope thanks to the closure.
Essentially, you can pass in any function and get a new function that returns the negated result of the original function in return. For example:
var isNotArray = negate(Array.isArray);
isNotArray(12);
//-> true
In fact, negate(isNaN) simply return a function to the variable isNotNaN. This function take a parameter (named x in your case), then execute the function isNaN on the parameter before negating it and returning the result.
Perhaps this example can clear some things out for you regarding closures:
function foo(x){
function bar(y){
return x+y;
}
return bar;
}
var fooRef = foo(1); // fooRef references foo() with x set to 1
console.log(fooRef(2), foo(1)(2)); // 3, 3
http://jsfiddle.net/ePwy8/
I need to get the value of a variable using its name. But I also need to consider the scope stuff. For example, my user may write the following code:
var x = 20;
function func1(){
var x = 30;
return function(){
return x;
}
}
var func = func1();
Now they pass me this func, and also a string named "x", and I need to evaluate x from the scope that func belongs to.
To be more clear, I need to implement a function, which takes two arguments, one is an object, the other is a string represent the variable name. The function need to return the value of the variable represented by the second argument from the scope that the first object belongs to.
function resolveValue(obj, name){
//unimplemented;
}
resolveValue(func, "x"); //return 20 in this example.
I think this can be done if I can get the scope chain, but is this possible in javascript?
function makeIncreaseByFunction(increaseByAmount) {
return function (numberToIncrease) {
return numberToIncrease + increaseByAmount;
};
}
makeIncreaseByFunction(3)(10);
Updated for Clarity
Can somebody explain why the (3)(10) is written the way it is? I understand that 10 is being supplied as an argument to the inner function, but why is syntactically notated like this? If we had three nested functions, would the arguments always be written in order as in (3)(10)(20)?
With intermediate variable:
var increaseBy3 = makeIncreaseByFunction(3);
var foo = increaseBy3(10);
Without intermediate variable:
var foo = makeIncreaseByFunction(3)(10);
In both cases, the first invokation passes the argument 3 to makeIncreaseByFunction, and as a result it returns the inner function that has closed over increaseByAmount with the value of 3. Whether you create a variable for the intermediate function returned by makeIncreaseByFunction, or just invoke it directly, it does the same thing.
Can you explain a little bit more detail about how in var foo = makeIncreaseByFunction(3)(10); the 10 is getting to the inner function? It just looks syntactically different from how arguments usually get passed in Javascript to me. – ggg
makeIncreaseByFunction(3) returns a function, specifically the "inner function" defined inside makeIncreaseByFunction. As will all functions, you call it with the function ( arguments ) syntax. You can write it like this if it makes more sense to you this way:
( makeIncreaseByFunction(3) )(10)
What happens here is makeIncreaseByFunction(3) gets called first and returns the ⟪inner function⟫, and then we call ⟪inner function⟫(10).
If you were evaluating this by hand (I think this is what you meant by "syntactically"), you could think of it happening step-by-step like this:
// Original invocation
var foo = makeIncreaseByFunction(3)(10);
// Substitute the definition of makeIncreaseByFunction
var foo = (function (increaseByAmount) {
return function (numberToIncrease) {
return numberToIncrease + increaseByAmount;
};
})(3)(10);
// Apply the parameter 3
var foo = (function (numberToIncrease) {
return numberToIncrease + 3;
})(10);
// Apply the parameter 10
var foo = 10 + 3;
// Final result
var foo = 13;
Note: If you want to be technical, all we're doing here is two Beta reductions—but unless you have background with the Lambda Calculus that will probably confuse you more than it will help you!
makeIncreaseByFunction(3) would return function so the syntax for then calling it with 10 would be makeIncreaseByFunction(3)(10).
This is easy to understand as if you have a function foo (imagine that the return of makeIncreaseByFunction(3) is such a function, they are evaluated identically), you would then call it with 10 using foo(10).
As for how the value of 10 is being 'passed', this is the wrong way to thing about things.
You must realise that in Javascript functions are first class objects.
Instead of passing the value to the inner function, you are creating a function that does what you want and then calling it with the outer argument.
It is the same as using a variable to add within a function in a non-functional language except functions can be dynamically created at runtime and the values of any variable in their definition can be set influencing their internal consistency.
The closure refers to the fact that the created function is a black-box which hides the variable used to initialize it, despite still using that variable to increment the value it is called with.
var increaseBy3 = makeIncreaseByFunction(3); is the exact same as (disregarding the local storage for the variable increaseByAmount):
var increaseBy3 = function (numberToIncrease) {
return numberToIncrease + 3;
};
So of course now you can call increaseBy3(10) and get 13. increaseBy3 just references as anonymous function which returns its first argument plus 3.