What's the difference between:
// Example 1 sum(8,2)
console.log(sum(8,2)); // Outputs what??
// Example 2 sum(8)(2)
console.log(sum(8)(2)); // Outputs what??
function sum(x,y) {
return x+y;
}
function sum(x) {
return function(y){
return x+y;
}
}
Why is one used over the other and why?
What you are trying to do is called Function Currying
Try this:
function sum(x) {
return function(y) { return x + y; }
};
var sumWith4 = sum(4);
var finalVal = sumWith4(5);
finalVal = sumWith4(8);
One of the advantages is that it helps in reusing abstract function. For example in the above example I can reuse sumWith4 to add 4 to any number with out calling sum(4,5) explicitly. This was a very simple example. There would be scenarios where in part of the function would be evaluated based on the first param and the other part on the second. So you can create a partial function by providing it with the first param and then reuse the partial function repeatedly for multiple different second params.
I will be assuming that you mean to ask the difference between the invocation of functions which appear like:-
someFunction(x, y)
someFunction(x)(y)
This happens with the use of Closures which happens to be a concept wherein an inner function can carry the environment in which it was created.
var sum = function (x){
return function(y) {
return x+y;
};
};
var addWith5 = sum(5);
/*
This will return a function and not a value
addWith5 = function(y){return 5+y;};
*/
console.log(addWith5(5)); // this will return 11
/*
You can also use add function directly
*/
console.log(sum(5)(6)); // this will return 11
/*
The function returned by sum(5), gets called with the parameter (6)
*/
//Try using this, to make it more clear
function a(x){
return x;
}(5);
// returns 5
EDIT
Removed "closures is a JS concept."
Related
I was looking how filters works in Angularjs and I saw that we need to send 2 sets of parentheses.
$filter('number')(number[, fractionSize])
What does it means and how do we handle it with JavaScript?
It means that the first function ($filter) returns another function and then that returned function is called immediately. For Example:
function add(x){
return function(y){
return x + y;
};
}
var addTwo = add(2);
addTwo(4) === 6; // true
add(3)(4) === 7; // true
$filter('number') returns a function that accepts two arguments, the first being required (a number) and the second one being optional (the fraction size).
It's possible to immediately call the returned function:
$filter('number')('123')
Alternatively, you may keep the returned function for future use:
var numberFilter = $filter('number');
numberFilter('123')
It is the same as this:
var func = $filter('number');
func(number[, fractionSize]);
The $filter() function returns a pointer to another function.
with ES6 or later versions you can do it that way;
const divideBoth = (x) => (y) => {
return x / y;
};
one of the reasons that makes this function type useful is when you have a react.js component that needs have callback function instead of doing it inline way(which is ()=>return value) you can do it the way we did previously. But it is not recommended to use in event callbacks because it gets execute in the first render which might cause issues sometimes
function multFn(num){
return function(factor){
return factor*num
}
}
var multFive=multFn(5)
console.log(multFive(2)) // outputs 10
The question?:
How does JS know that when I console.log(multFive(2)) that the 2 should be given to the factor parameter? I know that multFn will return a pointer to the method inside it. But I don't get how the 2 gets assigned to factor.
Calling the first function causes the inner one to be returned to your variable. When you invoke that function, the argument you pass goes to the parameter the second function is expecting.
When you run this first line:
var multFive = multFn(5);
The outer function (multFn) is invoked and 5 is received as num, so the function operates like this:
function multFn(5){
return function(factor){
return factor * 5
}
}
But, that function has a return in it that returns the inner function to your multFive variable, so you wind up with this:
var multFive = function(factor){
return factor * 5;
}
Finally, when you invoke multFive and pass it a 2, the 2 becomes the value of the factor argument that the function is expecting.
console.log(multFive(2));
Causes:
function(2){
return 2 * 5;
}
And, 2 * 5 = 10.
NOTE: I've shown what the functions will execute based on the code you've supplied. There is an advanced concept in JavaScript, called "Closures" that could make it so that the outer function doesn't always have to statically run with 5 as its value. But, for the purposes of your question, that's not relevant.
This is really an example of function currying. Essentially you are returning a function from a function, with some of the needed values already specified during the creation of the returned function.
Calling multFn(5) creates a closure around an anonymous function, and that closure has a reference to num as being 5.
The function that is returned is equivalent to:
function(factor){
var num=5;
return num * factor;
}
and is assigned to the reference multFive.
Inside your console.log(multFive(2)) you are calling that returned function multFive with the argument 2, and you get your result of 2*5=10.
I think your confusion because you think that the result of the assignment:
var multFive = multFn(5);
Will be something like this:
var multFive = function multFn(num) { //num is passed 5
return function(factor) {
return factor * num;
};
}
But that's not the case. It will actually be something like this:
var multFive = function(factor) {
return factor * num;
}
And the value 5 is assigned to the num variable in the closure. On the next line:
console.log(multFive(2));
You're passing 2 directly to the factor parameter and it will be multiplied by the value of num that was stored in the closure earlier.
To see that in action (a proof of that), print out the multFive:
console.log(multFive);
Here is a funny quiz, try to guess the output and then run it to see:
function multFn(num) {
setTimeout(function() {
num = 3;
}, 500);
return function(factor) {
return factor * num;
};
}
var multFive = multFn(5);
console.log(multFive(2)); // outputs 10
setTimeout(function() {
console.log(multFive(2)); //what will the output be here?
}, 1000);
Reading some legacy code, and found
A.prototype.setSize: function () {
var v1 = new Vector2();
return function (size ) {
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
this.min.sub( halfSize );
return this;
};
}(),
I am wondering:
why define setSize as a function which return another function
Also the defined function is executed right away.
any light to shed on this?
Updated:
I can simply use
A.prototype.setSize: function (size) {
var v1 = new Vector2();
var halfSize = v1.copy( size ).multiplyScalar( 0.5 );
this.min.sub( halfSize );
return this;
},
Is the first snippet better than second?
So the returned function can access the value of v1 each time it is called without making v1 a global (or otherwise non-private)
That is so the returned function is assigned to setSize
It function closure. Used to hide variables from global scope. Read on and see some examples here
JS function closures
The purpose in that particular case is to avoid creating a new Vector object each time setSize is called. It's a caching strategy. The alternative would be to just have a flat function:
A.prototype.setSize: function (size) {
var v1 = new Vector2();
var halfSize = v1.copy(size).multiplyScalar(0.5);
this.min.sub(halfSize);
return this;
}
I would only use the closure cached version of setSize if I found I was having performance problems because of new Vector2().
A classic example is:
function createAdder(x) {
return function add(y) {
return x + y;
}
}
var addTwo = createAdder(2);
// addTwo is a function that takes one input and adds 2 to it
addTwo(3); // 5
addTwo(9); // 11
The idea is that you want to create a function, but the function you want to create depends on something. In this case, we wanted to create an addX function.
See Chapter 5 of Eloquent Javascript for more. Particularly the Higher Order Functions section.
It also can be more DRY. Consider:
function createSecretAdder() {
var secretNumber = generateSecretNumber(); // THIS TAKES A LONG TIME
return function(n) {
return secretNumber + n;
}
}
var secretAdder = createSecretAdder(); // slow
secretAdder(2); // fast
secretAdder(7); // fast
vs.
function createSecretAdder() {
return function(n) {
var secret = getSecretNumber(); // THIS TAKES A LONG TIME
return secretNumber + n;
}
}
var secretAdder = createSecretAdder(); // fast
secretAdder(2); // slow
secretAdder(7); // slow
The former is DRYer and faster than the latter. This should address your comment and the update to your question.
Note: you'll have to understand closures to understand how this stuff works.
As for why it's immediately invoked, see here.
I'm trying to understand how a function works that is run with two parentheses and two parameters. Like so:
add(10)(10); // returns 20
I know how to write one that takes two params like so:
function add(a, b) {
return a + b;
}
add(10,10); // returns 20
How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
Any help is appreciated. Literally scratching my head over this.
Thanks in advance!
How could I alter that function so it could be run with one set of parameters, or two, and produce the same result?
You can almost do that, but I'm struggling to think of a good reason to.
Here's how: You detect how many arguments your function has received and, if it's received only one, you return a function instead of a number — and have that function add in the second number if it gets called:
function add(a,b) {
if (arguments.length === 1) {
return function(b2) { // You could call this arg `b` as well if you like,
return a + b2; // it would shadow (hide, supercede) the one above
};
}
return a + b;
}
console.log(add(10, 10)); // 20
console.log(add(10)(10)); // 20
I said "almost" above because just because the add function received only one argument, that doesn't guarantee that the caller is going to call the result. They could write:
var x = add(10);
...and never call the function that x now refers to.
Welcome to the wonderful world of first order functions
In JavaScript, a function can return a function since a function is just another object. A simple implementation is something like:
function add(x){
return function addOther(y){
return x + y;
};
}
This is possible because of closures and first order functions.
This also lets you do partial application, libraries like Ramda utilize this to great extent.
var addThree = add(3)
addThree(5); // 8
To extend what both T. J. Crowder and Benjamin Gruenbaum said, libraries like Ramda (disclosure: I'm one of the authors) allow you to convert a simple function like this:
function add(a, b) {
return a + b;
}
into the style under discussion by wrapping it in a call to a curry function:
var add = R.curry(function add(a, b) {
return a + b;
});
add(3, 5); //=> 8
add(3)(5); //=> 8
var add3 = add(3);
add3(5); //=> 8
The best article I know on this subject is Hugh Jackson's Why Curry Helps. I wrote a more detailed one at Favoring Curry.
Update
Here is a version of curry somewhat simpler than the one in Ramda. It would do the above and quite a bit more, but doesn't do some of the things that Ramda does with placeholder values:
// here is a function that takes a function and returns a curried version
// of it, that is, a version that performs the sort of partial application
// you describe.
var curry = function(fn) {
// first, we detect how many arguments the function has.
var fnArity = fn.length;
var partialApply = function(args) {
// now, let's create a function that's curried
return function () {
// collect the previous args as the partial, and add the new
// ones you just received
var newArgs = (args || []).concat([].slice.call(arguments, 0));
// if we have "enough" arguments, we don't need any more partial
// application and we can call the function.
if (newArgs.length >= fnArity) {
return fn.apply(this, newArgs);
} else { // else we return a partially applied version
return partialApply(newArgs);
}
};
};
return partialApply([]); // a function is itself partially applied with 0 args
};
function add() {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
function total() {
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return total;
}
total.toString = function () { return sum };
return total;
}
This will work for any no of arguments and parentheses.
https://medium.com/#imdebasispanda/super-function-with-closure-86a58a9a980b
I was looking how filters works in Angularjs and I saw that we need to send 2 sets of parentheses.
$filter('number')(number[, fractionSize])
What does it means and how do we handle it with JavaScript?
It means that the first function ($filter) returns another function and then that returned function is called immediately. For Example:
function add(x){
return function(y){
return x + y;
};
}
var addTwo = add(2);
addTwo(4) === 6; // true
add(3)(4) === 7; // true
$filter('number') returns a function that accepts two arguments, the first being required (a number) and the second one being optional (the fraction size).
It's possible to immediately call the returned function:
$filter('number')('123')
Alternatively, you may keep the returned function for future use:
var numberFilter = $filter('number');
numberFilter('123')
It is the same as this:
var func = $filter('number');
func(number[, fractionSize]);
The $filter() function returns a pointer to another function.
with ES6 or later versions you can do it that way;
const divideBoth = (x) => (y) => {
return x / y;
};
one of the reasons that makes this function type useful is when you have a react.js component that needs have callback function instead of doing it inline way(which is ()=>return value) you can do it the way we did previously. But it is not recommended to use in event callbacks because it gets execute in the first render which might cause issues sometimes