I recently started to learn javascript by myself and I am reading a book called "Eloquent JavaScript". The following code is a sample script in the book which confused me:
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
Can someone please explain the logic of the last two lines? Does the greaterThan10 contain a truth value or it is a function?
You define greaterThan10 on the second to last line:
var greaterThan10 = greaterThan(10);
Whatever the greaterThan function returns in this case is what greaterThan10 will evaluate to.
On line 2 we see that greaterThan will return the following function expression:
function(m) { return m > n; }
After replacing the variable n with the value you passed we get this:
function(m) { return m > 10; }
It can look a little confusing at first, but just keep in mind that functions are objects in JavaScript.
greaterThan(n) is a function that returns an anonymous function with the definition:
function(m) { return m > n; }
Therefore, when we call greaterThan(10) we expect it to return an object that is in fact a function:
function(m) { return m > 10; }
Later on we just assign that object/function to a variable, and call it like we would call any function.
In short, just imagine that we had:
var greaterThan10 = function(m) { return m > 10; };
Related
function person1(name) {
var n = name;
return (function (n) {
alert(n);
})(n);
}
person1('susan')();
person1('peter')();
The second statement cannot be run, anyone can give me a correct explanation.
person1('susan') does not return a function, it returns undefined, so you can't call it afterwards - the extra () results in the script throwing.
If you want calling person1 to return a function that, when called, alerts the name, remove the n parameter, and return a function that alerts name - but don't call the function, just return it, so the returned function can be called outside:
function person1(name) {
return () => {
console.log(name);
};
}
person1('susan')();
person1('peter')();
The code of your function is basically ok but the call person1 is not. You should omit the brackets after the call. Because your not returning a function back from person1. Actually you don't have a return value at all.
function person1(name) {
var n = name;
return (function (n) {
alert(n);
})(n);
}
person1('susan');
person1('peter');
This would work but can be simplified.
Can someone please explain the below 'Currying' function. When I set a break point, I can see values 'b' and 'c' are undefined and returned. But how does the system get the value 7 for 'b' and 9 for 'c' in this case. Its printing the correct result for 5*7*9, ie 315 in console.
function multiply(a){
return function (b){
return function (c) {
return a*b*c ;
}
}
}
var answer = multiply(5)(7)(9);
console.log(answer);
When you call multiply(5) a function is returned and that function is immediately called with multiply(5)(7) and have access to a and b, then a new function is returned and is also immediately called when multiply(5)(7)(9) and has access to a, b, and c.
The answer to why the nested functions have access to parent function parameters is closures. Please check this other question/answers about closures in javascript: link.
You can understand currying if you assign each intermediate result to a variable. Rewrite the function calls like this:
var x = multiply(5)
var y = x(7);
var answer = y(9);
Now it is more clear that the result of calling multiply(5) is a function. We call it with x(7) which passes the value of 7 to b. This results in another function which we call with y(9) which in turn passes the value of 9 to c and returns the final result.
When you call the multiply function, the important thing is each function returns an anonymous function. It will be easier if you give them names.
function multiplyA(a){
return function multiplyB(b){
return function multiplyC(c) {
return a*b*c ;
}
}
}
// When you call multiplyA(5)(7)(9)
// From the first, multiplyA(5) returns multiplyB with scope with multiplyA
// just like below
const a = 5;
const multiplyB = function(b){
return function multiplyC(c) {
return a*b*c ;
}
}
// Once more call multiplyB(7)
// It also returns function named multiplyC
const a = 5;
const b = 7;
const multiplyC = function(c) {
return a * b * c;
}
// Finally call mulitplyC(9) means 5 * 7 * 9
To understand it, closure and function scope will be helpful.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures
I've just started to learn javascript and come across one task that I don't understand. Can anyone explain me why do we return function name "return f" in this example and what for do we use "f.toString"?
function sum(a) {
var currentSum = a;
function f(b) {
currentSum += b;
return f;
}
f.toString = function() {
return currentSum;
};
return f;
}
alert( sum(1)(2) ); // 3
alert( sum(5)(-1)(2) ); // 6
alert( sum(6)(-1)(-2)(-3) ); // 0
alert( sum(0)(1)(2)(3)(4)(5) ); // 15
Lets start with a simplified version:
function sum(currentSum) {
return function f(b) {
currentSum += b;
return f;
}
}
It willwork much like yours, you can do:
sum(1)(2)(3);//f
sum(1)(2);//f
However, they always return a function, so were not able to access the currentSum. Its in sums scope and as its never returned or passed, its impossible to get it. So we probably need another function we can call to get the current sum:
function sum(currentSum) {
function f(b) {
currentSum += b;
return f;
}
f.getSum = function() {
return currentSum;
};
return f;
}
So now f has a property (functions are objects too), which is a function called getSum to get our variable
sum(1)(2)(3)//f
sum(1)(2)(3).getSum()//6 <= wohhooo
But why do we call it toString ?
When adding a variable to a string, its converted to a string, e.g.
1+"one"//"1one"
the same applies to objects/functions, but in this case, the js parser tries to call their toString method first, so:
sum(1)(2)+"three"
equals
sum(1)(2).toString()+"three"
the same conversion happens when passing non strings to alert.
You are returning the object. So you can call the function again and, in the second call, you will have a currentSum allready.
when you do sum(3) the function will hold the number 3 and when you call it again doing sum(3)(4) it will add 4 to the currentSum.
then the alert will call the toString method and it will print the sum
look at the first example
alert( sum(1)(2) ); // 3
sum(1) // will return f. sum must return a function in order for the syntax to work
after it will return f it will become:
alert( f(2) );
With function sum you are passing the first argument a and returning function f which sum currentSum with the argument passed to f (b) and return again f and you can do that many times you want at the end it will call alert function which needs its first argument to be string. For that purpose you have rewritten the method on function f toString which in this case will return the currentSum.
Every object has a toString() method that is automatically called when the object is to be represented as a text value.
This is the task for understanding the type system of JavaScript. The task is to make function that adds numbers using currying. The idea is to make function that adds numbers when called like this sum(1)(2)(3), as you written in the task.
What do we do (looking to your code) in function sum:
1.
var currentSum = a;
Here you declare a sum variable in scope of function sum.
function f(b) {
currentSum += b;
return f;
}
Then you declare the function that will perform summation. It returns itself for possibility of doing such thing: f(1)(2)(3)
3.
f.toString = function() {
return currentSum;
};
After that you declare that f, converted to string returns sum value
Than you return f to start adding.
Than what about f.toString - it 's being called, when f is passed alert as an argument. That's automatic casting of javascript
My task is to write a higher order function for chaining together a list of unary functions.The first argument is an array, which holds the names of functions to be called.The second param is the value to be used with functions. Here is the code
function square (x) {return x * x;}
function add3 (x) {return x + 3;}
function chainer(a) {
return function (b) {
for(var i = 0; i < a.length; i++) {
return a[i](b)
}
}
}
console.log(chainer([square, add3])(4));
The desired output is 19 but it executes only the first function and prints out 16. I think I would need to compose these functions somehow but can`t wrap my head around it. Would I need to use apply() or call() methods to complete the task? I am new to functional programming.
Your problem is that return a[i](b) does only call the first function and immediately return its result. You will need to put the return after the loop:
for (var i = 0; i < a.length; i++) {
b = a[i](b)
}
return b
Alternatively, this is a great use case for reduce/fold (which you probably have encountered before function composition):
return function(b) {
return a.reduce(function(b, f) { return f(b) }, b)
};
or even
return a.reduce(compose, function id(x) { return x; });
I'm learning to code and I'm trying to understand Higher Order Functions and abstractions. I don't understand how this piece of code runs to return "true".
function greaterThan(n) {
return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
Thanks for the help.
The function greaterThan returns a function when called. The returned function has access to all the members of the outer function even after the function has returned. This is called closure.
function greaterThan(n) {
return function (m) {
return m > n;
};
}
When following statement is executed
var greaterThan10 = greaterThan(10);
it is converted as
var greaterThan10 = function (m) {
return m > 10;
};
So, greaterThan10 is now the function and can be called as
console.log(greaterThan10(11));
Now, value of m is 11 and return 11 > 10; returns as true.
Read more about closures:
How do JavaScript closures work?
Also, I'll recommend following great article to all the JS developers
http://dmitryfrank.com/articles/js_closures