This question already has answers here:
What is 'Currying'?
(23 answers)
Closed 4 years ago.
I recently found JavaScript code like this:
someFunction()()
Function immediately invoked right after function without classic IIFE syntax.
What is that kind of syntax called? And how it works?
Its a function that returns another function.
Here is an example on how it works, this can help you to understand better.
function sum(x){
return function(y){
return x+y;
}
}
sum(3)(5); //8
For you code to work:
someFunction()();
You need to have code that looks like this:
function someFunction() {
console.log('someFunction()');
// do something before return
return function() {
console.log('someFunction()()');
// do something else here
}
}
someFunction()();
In this example you first call someFunction then you call the function that was returned by someFunction.
This can be good to do when you need to pass in a variable that will be used in the inner function but the inner function will be called in the future like this:
function someFunction(outerVal) {
console.log('Outer called.');
return function(innerVal) {
console.log('inner called.');
return outerVal * innerVal;
}
}
var inner = someFunction(12);
setTimeout(()=> {
console.log(inner(4));
}, 1000);
I use this often in Node.js for common middle-ware that needs a single value to be unique.
app.get('/dogs', myFn('woof'));
app.get('/cats', myFn('meow'));
app.get('/birds', myFn('tweet'));
function myFn(word) {
return function(req, res, next) {
res.write(word).end();
}
}
That is an over simplification, but can be vary powerful.
Related
This question already has answers here:
What is 'Currying'?
(23 answers)
Closed 4 years ago.
I have a javascript coding exercise to do which has got me a bit stuck (I'm only just starting javascript).
The exercise is as follows:
Write a function multiply(a) that returns a function capable of multiplying by a. Call this function with b as a parameter.
So far I have the main skeleton (not difficult):
function multiply(a) {
return //Stuck here
}
I'm not sure if the question is to call multiply(b) and have it give us the result of a*b or something else...
I tried writing a function directly after the return statement but this just printed out the function name.
function multiply(a) {
return function f { return a * b } //Here I assume b is a variable defined somewhere
}
Thanks in advance!
You could take a closure over the variable and return a function for the multiplication for the multiplicand.
function multiply(a) {
return function (b) {
return a * b;
}
}
var threeTimes = multiply(3);
console.log(threeTimes(7));
This question already has answers here:
What do multiple arrow functions mean in JavaScript?
(7 answers)
Closed 6 years ago.
Can anyone explain what the code is doing here
return () => next => action => {
const callAPI = action[CALL_API];
if (typeof callAPI === 'undefined') {
return next(action);
}
let { endpoint } = callAPI;
const { types, bailout } = callAPI;
It is initially returning a function but I don't get why there are two further fat arrows after the first.
If the arrow function has only one parameter, then the parameter around that is optional. You just need to have enough parenthesis to understand them better.
return () => (next) => (action) => {
it returns a function, which when invoked returns another function which accepts one parameter, next. Now when that function is invoked, it returns another function, which accepts another parameter action.
That code can be rewritten like below,
return function() {
return function(next) {
return function(action) {
It seems that the outer function returns a function with parameter next and that returns another one function with parameter action. That code in the link that you given has not minified, but that seems to be obfuscated.
This question already has an answer here:
Anonymous function declaration shorthand javascript
(1 answer)
Closed 7 years ago.
This is the code I have got,
var MyNameSpace.ShoppingList = {
addItem: function (itemName, functionName, listName) {
$("<li>", { text: itemName })
.on("click", functionName)
.appendTo($("#" + listName));
},
};
then in another module,
var MyNameSpace.ModuleX = {
init: function () {
MyNameSpace.ShoppingList.addItem("Get Eggs From Market", alert("Run Me when listItemClicked"), "shoppingpoplist");
},
};
Question
I want alert("Run Me when listItemClicked") to run only when listitem is clicked...
I already know changing it to this helps,
MyNameSpace.ShoppingList.addItem("Get Eggs From Market", function () { alert("Run Me when listItemClicked"); }, "shoppingpoplist");
But above solution makes my code very long, so there's no point for me adding a separate addListItem, can I solve above issue with least number of code ? Do I must need to add function () {}... either where alert is called or in the addListItem method itself
If it's common practice to do so, then am I on right track of putting addItem in a separate method here ?
With ES6, you get arrow functions, which shorten things considerably:
MyNameSpace.ShoppingList.addItem("Get Eggs From Market",
() => alert("Run Me when listItemClicked"), "shoppingpoplist");
// ^^^^^ equivalent to function() { return ... }
If you can't use arrow functions (which are supported in latest versions of Chrome and Firefox, but not IE11 and below), you can do something like this if you really want:
function handleWithAlert(msg) {
return function() { alert(msg); };
}
MyNameSpace.ShoppingList.addItem("Get Eggs From Market",
handleWithAlert("Run Me when listItemClicked"), "shoppingpoplist");
handleWithAlert() will return a function, which is what's expected to be passed as the first parameter. So you get a generic event handler generator for alert messages.
The syntax alert(..) will call alert immediately and pass its return value into addItem. What you need instead is to pass a function that when called will execute alert(..). There are pretty much three options for this:
function () { alert(..); }
or:
alert.bind(null, '..')
or:
function callback() {
alert(..);
}
addItem(.., callback)
Take your pick. It doesn't get any shorter.
This question already has answers here:
Calling a function that's defined inside a function
(3 answers)
Closed 8 years ago.
I have the next in JS:
function doC() {
this.try = document.getElementById("try");
function tryC(){
//do something
}
}
Now, I want to call tryC function, when so I wrote the next:
<script type="text/javascript" src="myFile.js"></script>
<script type="text/javascript">tryC();</script>
But as I see, nothing happen. Ho I call tryC()?
You have defined C in the scope of doC. It is not accessible outside of doC.
If you want it to be accessible globally, then you have to explicitly assign it a global.
window.C = function () { /* etc */ };
Creating globals is usually a bad idea, more so when they aren't created at load time. There is probably a better way to achieve whatever problem you are trying to solve with this.
Your tryC is defined inside doC, it's not exposed (it's private), you can do:
function doC() {
this.try = document.getElementById("try");
return function(){
alert('Try C');
}
}
doC()(); // alerts
or
function doC() {
this.try = document.getElementById("try");
return {
tryC : function(){
alert('Try C');
}
}
}
doc().tryC(); //alerts
Or your way (globals all around)
function doC() {
this.try = document.getElementById("try");
this.tryC = function(){
alert('Try C');
}
}
doC(); // call first!
tryC(); // alerts
This question already has answers here:
Pass an extra argument to a callback function
(5 answers)
Closed 6 years ago.
I want to something similar to this:
function AjaxService()
{
this.Remove = function (id, call_back)
{
myWebService.Remove(id, CallBack)
}
function CallBack(res) {
call_back(res);
}
}
so my calling program will be like this:
var xx = new AjaxService();
xx.Remove(1,success);
function success(res)
{
}
Also if I want to add more parameters to success function how will I achieve it.
Say if I have success function like this:
var xx = new AjaxService();
//how to call back success function with these parameters
//xx.Remove(1,success(22,33));
function success(res,val1, val2)
{
}
Help will be appreciated.
Use a closure and a function factory:
function generateSuccess (var1,var2) {
return function (res) {
// use res, var1 and var2 in here
}
}
xx.Remove(1,generateSuccess(val1,val2));
What you're passing here is not the generateSuccess function but the anonymous function returned by generateSuccess that looks like the callback expected by Remove. val1 and val2 are passed into generateSuccess and captured by a closure in the returned anonymous function.
To be more clear, this is what's happening:
function generateSuccess (var1,var2) {
return function (res) {
// use res, var1 and var2 in here
}
}
var success = generateSuccess(val1,val2);
xx.Remove(1,success);
Or if you prefer to do it inline:
xx.Remove(1,(function(var1,var2) {
return function (res) {
// this is your success function
}
})(val1,val2));
not as readable but saves you from naming the factory function. If you're not doing this in a loop then Xinus's solution would also be fine and simpler than my inline version. But be aware that in a loop you need the double closure mechanism to disconnect the variable passed into the callback function from the variable in the current scope.
You can pass it as anonymous function pointer
xx.Remove(1,function(){
//function call will go here
success(res,val1, val2);
});
one way to do this:
function AjaxService {
var args_to_cb = [];
this.Remove = function (id, call_back, args_to_callback_as_array) {
if( args_to_callback_as_array!=undefined )
args_to_cb = args_to_callback_as_array;
else
args_to_cb = [];
myWebService.Remove(id, CallBack)
}
function CallBack(res) {
setTimeout( function(){ call_back(res, args_to_cb); }, 0 );
}
}
So you can use it like this:
var service = new AjaxService();
service.Remove(1,success, [22,33]);
function success(res,val1, val2)
{
alert("result = "+res);
alert("values are "+val1+" and "+val2);
}
I usually have the callback execute using a setTimeout. This way, your callback will execute when it gets the time to do so. Your code will continue to execute meanwhile, e.g:
var service = new AjaxService();
service.remove(1, function(){ alert('done'); }); // alert#1
alert('called service.remove'); // alert#2
Your callback will execute after alert#2.
Of course, in case of your application, it will happen so automatically since the ajax callback itself is asynchronous. So in your application, you had better not do this.
Cheers!
jrh