I am Following http://eloquentjavascript.net/05_higher_order.html. I have following piece of code
function findEven(number, body) {
for(var i = 0; i < number; i++) body(i)
}
function unless(test, then) {
if(!test) then();
}
findEven(10, function (n) {
unless(n%2, function (n) {
console.log(n, 'is even')
});
});
My question is if i pass variable n into function unless it prints the value 'undefined' to the console. I dont understand why the function unless does not hove the access to its outer scope. Could someone please explain the reason?
Look here
function unless(test, then) {
if(!test) then();
}
And here
unless(n%2, function (n) {
console.log(n, 'is even')
});
The unless function doesn't pass anything to that callback which takes n, so n is undefined.
probably just remove the n from the callback so that it is
unless(n%2, function () {
console.log(n, 'is even')
});
findEven(10, function (n) {
// remove n as an input param
unless(n%2, function () {
console.log(n, 'is even')
});
});
You dont need n inside since you have it as a closure.
Since you are invoking then() without any param - n is undefined.
The outer n is overridden with the inner scope n.
n is undefined because the function then() is called without any argument. The problem lays when you define the function passed in to unless.
The argument n overrides the variable n already defined in the closure. Therefore, because then() is called without arguments, n assumes the value undefined and the console prints undefined.
To fix the bug, just remove n from the arguments:
unless(n%2, function () {
console.log(n, 'is even')
});
JSFiddle : https://jsfiddle.net/5tvafuqt/
Related
I am new to JavaScript and have several questions about functional programming.
Here is a statement:
outer(inner(5));
Is it possible to construct function outer in a way that allows it
to capture function inner and its argument 5?
Is it possible to construct function inner in a way that allows it to
pass itself and its argument 5 to function outer?
If the answer to both questions above is no, is it possible to
construct functions outer and inner in a way that allows the former
to capture function inner and its argument 5 or the
latter to pass itself and its argument 5 to function
outer?
I tried:
using the arguments object but to no avail.
function outer (parameter) {
return arguments;
}
function inner (n) {
return n + 1;
}
console.log(outer(inner(5))); // returns Arguments { 0: 6 ... }
using currying but I do not see how it can help me since I am not given the following statement:
outer()(5);
A possible workaround consists in returning an array from inner() composed of on one side the processing function and on the other side the argument.
outer will be able to access both by reading the array.
function outer(arr)
{
var fun = arr[ 0 ];
var arg = arr[ 1 ];
var result = fun(arg);
console.log('inner function is:', fun);
console.log('its argument is:', arg);
console.log('its result is:', result);
return result;
}
function inner(num)
{
return [
function (_num)
{
return _num + 1;
},
num
]
}
console.log(outer(inner(5)));
You could achieve this by letting your inner return a function (foo) which closes over n. You can then let foo return n+1. Then, within your outer function, you can invoke foo to get its return value:
const outer = f => f();
const inner = n => _ => n+1;
console.log(outer(inner(5)));
Alternatively, another possibility would involve changing your return value. You could return an array from inner which contains the original passed through arguments (...arguments) and the returned value (to_return) and then use destructuring assignment to get the passed in argument(s) (n & m) and the returned result:
function outer([result, n, m]) {
console.log("returned from inner: ", result);
console.log("arguments passed into inner: " + [n, m]);
return n;
}
function inner(n, m) {
let to_return = n + 1;
return [to_return, ...arguments];
}
console.log(outer(inner(5, 2))); // returns 5
Note: I added an m argument to demonstrate how you can extend this to multiple arguments
function outer(myFunction, argument) {
if (typeof myFunction !== "function") {
return false;
}
return myFunction(argument);
}
function inner(n) {
return n + 1;
}
console.log(outer(inner, 5));
Just a simple approach. Don’t execute the function inner but pass it as an argument (myFunction). And let the outer function execute it with the given argument.
Currently I'm reading JavaScript book. There is a code snippet in it which I can't understand. What's happening in the line repeat(3, function(n) {? Why we can pass parameter n to the second argument of the function repeat, because in its declaration there is nothing about passing parameters? How does repeat understand that it should pass parameter n to the unless function?
function unless(test, then) {
if (!test) then();
}
function repeat(times, body) {
for (var i = 0; i < times; i++) body(i);
}
repeat(3, function(n) {
unless(n % 2, function() {
console.log(n, "is even");
});
});
// → 0 is even
// → 2 is even
Why we can pass parameter n to the second argument of the function repeat, because in its declaration there is nothing about passing parameters
You are not passing n as the second argument to repeat(), you are passing an anonymous function that takes a single parameter and you chose to name its parameter n (so parameter of the function that is passed in)
Functions in JavaScript are, in simple words, just objects that can also be executed. This means you can pass functions around as parameters to other functions, or add properties to them like you would to objects, etc.
Here's an illustration of what is happening in your example:
Function repeat is defined with two arguments:
repeat(times, body)
So, all you are doing is passing a function as the body argument.
Writing it like this is equivalent:
var times = 3;
var body = function(n) {
unless(n % 2, function() {
console.log(n, "is even");
});
};
repeat(time, body);
How does repeat understand that it should pass parameter n to the unless function?
As you can see above, repeat is not passing anything to unless().
It is your anonymous function (stored in body in my example above) that is actually passing n to unless.
You're not passing a parameter n at all.
In reality, you're passing an entire anonymous function as a parameter (functions are first-class citizens in JavaScript and can be passed around just like other variables).
If you look, the function is passed as the body parameter to the method repeat. repeat then calls the function body with the parameter of i...which is the parameter n in the anonymous function.
If you simply want to write a function to repeat x number of times, and check if it's even, you'd probably want to do it like this:
function repeat(times) {
for (var i = 0; i < times; i++) {
output.innerHTML+= is_even(i)+"\n";
}
}
function is_even(n) {
if ( n % 2 ) return n+" is even";
return n+" is odd";
}
var output = document.getElementById('output');
repeat(6); // Output variable wasn't passed to this function, we're using it globally
<pre id='output'></pre>
The code is from Eloquent Functional Programming. I have trouble understanding the test(element). If the test(element) is referencing equals(x), then is element = 0 since there is only one parameter?
function count(test, array) {
return reduce(function(total, element) {
return total + (test(element) ? 1 : 0);
}, 0, array);
}
function equals(x) {
return function(element) {return x === element;}; // element gets value from x?
}
function countZeroes(array) {
return count(equals(0), array);
}
Previous code
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
function reduce(counter, base, array) {
var total = 0;
forEach(array, function (element) {
total += counter(element);
});
return total;
}
element does not get its value from x.
Rather, element refers to a parameter which will have it's value supplied when the function is invoked - by count in this case. The variable x, a parameter in the outer scope, is bound in scope of the function/closure that is returned when equals is invoked. That is, equals(0) evaluates to a function/closure which is then used as a predicate to count.
First, let's use equals directly, bearing in mind that equals evaluates to a function as does equals(0):
equals(0)(1) // -> false, x=0, element=1
equals(0)(0) // -> true, x=0, element=0
// ^^^^^^^^^ - invokes equals(..), evaluates to the closure binding `x`
// ^^^ - invokes the previously returned closure, supplying `element`
But because that's a bit hard to abstractly see, let's give the closure a name:
var equalToZero = equals(0) // -> function, x=0
// ^^^^^^^^^ - invokes equals(..), evaluates to the closure binding `x`
equalToZero(1) // -> false, x=0, element=1
equalToZero(0) // -> true, x=0, element=0
// ^^^^^^^^^^^^^^ - invokes the previously returned closure, supplying `element`
// And just as before, it is the `count` function that
// supplies the `element` argument when it invokes the function.
// (The function is locally known by the name `equalToZero`.)
count(equalToZero, array);
Which we could imagine was written like this:
function equalToZero (element) {
return 0 === element;
}
The difference being, of course, that in the above function the value (0) is hard-coded, while in the closure-creating equals it is whatever the bound x variable evaluates to.
(For more wonderful goodness on closures, see How do JavaScript closures work?)
I am trying to undrstand the code
for(var i = 0; i < 10; i++) {
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
}
from here http://bonsaiden.github.com/JavaScript-Garden/#function.closures
I understood this method :
for(var i = 0; i < 10; i++) {
(function(e) {
setTimeout(function() {
console.log(e);
}, 1000);
})(i);
}
Can anyone please help me by explaining the first one?
I will try to explain how I understands the first one,
first i is 0,
setTimeout is called,
self calling function "function(e)" is called with i=0,
Im stuck!! what happens when this function returns a function?
All the first one does is return a function that will be called after the timeout happens.
The purpose of it is to create a sub-scope for each iteration of the for loop so that the incrementing i isn't overridden with each iteration.
More explanation:
Lets take this apart into two different pieces:
for(var i = 0; i < 10; i++) {
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
}
This is the first piece:
for(var i = 0; i < 10; i++) {
setTimeout(function(){
console.log(i); //9-9
},1000);
}
Now, when you run this loop, you will always get console.log()'s that contain 9 instead of 0 to 9. This is because each setTimeout is using the same reference to i.
If you wrap the setTimeout part of that in an anonymous function, it creates a scope for each iteration allowing each setTimeout to have it's own i value.
for(var i = 0; i < 10; i++) {
setTimeout((function(i) {
return function() {
console.log(i); // 0-9
}
})(i), 1000)
}
The outer function inside the setTimeout gets executed immediately with an i of 0 for first iteration, 1 for second, etc. That function then in turn returns a function which is the function that setTimeout uses. A function is being generated and returned for each iteration of the loop using a different value for i.
Both end up with the same result: a setTimeout is called with a function to invoke, which writes a number from 0 to 9 on the console. Both use nested functions to get the current value of i into a closure so you don't end up logging 10 9's.
The first code chooses to have a function returning the function that setTimeout will call. The second changes the nesting order so that the closed-over function invokes setTimeout itself. The net effect is the same.
Other than stylistic reasons and personal choice, I don't see a reason to choose one over the other.
"Can you please check the updated question specifying where im getting confused"
OK, here's the long explanation. Remember that the first parameter to setTimeout() needs to be a reference to the function that you want executed after the specified delay. The simplest case is to just name a function defined elsewhere:
function someFunc() {
console.log("In someFunc");
}
setTimeout(someFunc, 100);
Note there are no parentheses on someFunc when passing it as a parameter to setTimeout because a reference to the function itself is required. Contrast with:
setTimeout(someFunc(), 100); // won't work for someFunc() as defined above
With parenthese it calls someFunc() and passes its return value to setTimeout. But my definition of someFunc() above doesn't explictly return a value, so it implicitly returns undefined - which is like saying setTimeout(undefined, 100).
But it would work if changed someFunc() to return a function instead of returning undefined:
function someFunc() {
return function() {
console.log("In the function returned from someFunc");
};
}
So now (at last) we come to the code from your question:
setTimeout((function(e) {
return function() {
console.log(e);
}
})(i), 1000)
Instead of referencing a function by name and calling it as someFunc(i) it defines an anonymous function and calls it immediately as (function(e) {})(i). That anonymous function returns another function and it is that returned function that becomes the actual parameter to setTimeout(). When the time is up it is that returned function that will be executed. Because the (inner) function being returned is defined in the scope of the (outer) anonymous function it has access to the e parameter.
Ok my questions comes from an example from a book that i'm trying to understand.Keep in mind i just got into javascript.
So we have the object set and we define the function foreach. It takes another function as a parameter and invokes it for every item of an array "values" that belongs to set.
set.foreach = function(f,c) {
for(var i = 0; i < this.values.length; i++)
f.call(c,this.values[i]);
};
So far so good..
But i can't understand the usage of the foreach function in the second snipet.In particular i don't understand the role of the variable v. It is not defined enywhere else in the book and i m having a really hard time to understand how this work.We define another function in set to take the values as an array
set.toArray = function() {
var a = [];
this.foreach(function(v) { a.push(v); }); //where did v came from???
return a;
}
set.foreach = function(f,c) {
for(var i = 0; i < this.values.length; i++)
f.call(c,this.values[i]);
}; // ^-------------- being passed right here
The function you passed in is f, and f is invoked having the this value of its calling context set to c, and this.values[i] passed as the first argument.
// ------v---------your function "f" in the forEach
this.foreach(function(v) { a.push(v); });
// ------------^------references the first argument (after the "this" arg)
// that was passed to "f"
Here's a simpler example:
This function accepts a function as a parameter. The only thing it does is call the function:
function my_func( fn ) {
fn();
}
// call my_func, which will call the function you give it
my_func( function() { alert( "hi" ); } );
Live Example: http://jsfiddle.net/6a54b/1/
...so passing the function to my_func will alert the string "hi". No surprise.
But what if my_func provided the value to be alerted?
function my_func( fn ) {
fn( "message from my_func" ); // call the fn passed, giving it an argument
} // ^------------------------------------------------|
// |
// v------references the arg passed by my_func---|
my_func( function( arg ) { alert( arg ); } );
Live Example: http://jsfiddle.net/6a54b/
Now you can see that an argument is being passed to the function we're sending over, and we reference that argument with the arg parameter.
It alerts whatever my_func gave it.
We can even take it one step further, by passing a second argument to my_func that my_func will simply take and pass it to the function we pass in.
function my_func( fn, str ) {
fn( str ); // call the fn passed, giving it
} // the string we passed in
// v------the arg we passed here-----v
my_func( function( arg ) { alert( arg ); }, "I'm getting dizzy!" );
Live Example: http://jsfiddle.net/6a54b/2/
And you can see that both arguments are given to my_func, and my_func calls the function we passed in, passing it the string argument we gave it.
The variable vis an argument being passed to the function. It allows you to work with whatever the function receives. It is no different than namein the following example:
function sayHello(name) {
console.log('Hello '+name);
}
f.call mean calling function f with arguments this.values[i]. this in foreach is set.
about calling foreach from toArray, passing function with v, the values[i] in foreach become v in toArray.
v in this case is being passed in from the call statement f.call(c, this.values[i]). Specifically, it is this.values[i]
The above statement is equivalent to simply:
f(this.values[i])
where f is the function in your 2nd snippet (function(v){ a.push(v); });)
The reason it's typed as .call instead of just calling it is so that the this property can be set, so this in your 2nd function is the array itself, meaning you could type:
function(v){
alert(this.length); // "this" == array
}
v represents each item in the list as your foreach() function loops through them.
so if you have 10 items in your "set" the function will be called 10 times, providing each item in the set to the function as argument v
for example:
set = [1,2,3,4,5];
set.foreach = function(fn, context) {
for(var i = 0; i < this.values.length; i++) {
fn.call(context, this.values[i]);
}
};
set_times_2 = [];
set.foreach(function(item) {
set_times_2.push(item);
set_times_2.push(item);
});
// this is true now:
set_times_2 == [1,1,2,2,3,3,4,4,5,5];
Lots of answers, here's one that specific to your question.
> this.foreach(function(v) { a.push(v); }); //where did v came from???
In the function expression passed to foreach, v is a formal parameter. Including an identifier as a formal parameter is more or less equivalent to declaring it in the function body with var. Maybe it's clearer if written as:
this.foreach( function (v) {
a.push(v);
});
or not...