What is the name of a function with four parentheses - javascript

For example:
const factory = {
myFunc(str1) {
console.log(str1)
return (comp) => {
return comp;
}
}
}
console.log(factory.myFunc("foo")("bar"));
The myFunc has four parentheses: factory.myFunc("foo")("bar").
How do you call such a function?

Its called function currying.
Actually read it like factory.myFunc("foo") is returning a function (say x) and calling that function immediately with "bar" argument (like x("bar")).

I don't know about the name, but what you are describing is actually two seperate functions. myFunc simply returns another function.
The line factory.myFunc("foo")("bar") first runs the myFunc funtion with foo as a parameter, this returns another function, which is then immediately run with the parameter bar.

It takes 2 parentheses & 1 argument to call myFunc, you need other 2 parentheses & 1 argument to call function it returns.
This sequence of calls is commonly called chaining of function calls. Sometimes, this sequence of actions is also referred to as pipe.
There's also such a term as currying but I'd say it rather describes a technique of declaring functions in a special way that enables you to pass arguments 1 by 1.
In this case, however, I wouldn't say it's currying since myFunc does something that has nothing to do with what returned function does while in currying (as it understood in Lodash for instance) all intermediate function calls serve just for passing arguments while the only function that does some actual job after collecting all arguments is the last one.
I would call myFunc just "method of factory".
It's also a higher order function as #ASDFfgerte correctly points out in comment.

Related

how does the returned function of JavaScript debounce function get all parameters through arguments

generally for js debounce function, a simple implement goes like
function debounce(func, wait) {
let timerId = null;
return function (...args) {
console.log('args',args);
clearTimeout(timerId);
timerId = setTimeout(() => func.apply(this, args), wait);
}
}
and when you use it, you can do things like
var random = function() {console.log(arguments)};
var test = debounce(random, 1000);
test(1,2,3);
my question is, how does the returned function inside debounce function can get all attributes that gets passed into test function (here being 1,2,3) through arguments object? I feel like it might have to do with closure, but can anyone explain?
I've also created a jsFiddle for simpler view
https://jsfiddle.net/u4n07veb/22/
Another question would be in this js fiddle, my console.log args can print 1,2,3, since 1,2,3 is what I pass to test function, but would it also be possible to get 4,5,6 inside the debounce function? Since 4,5,6 is the parameters I pass to the callback function of the debounce function?
Though the arguments special object does exist in JavaScript, in the implementation of debounce above the function arguments are instead retrieved via a rest parameter.
The difference is minimal - arguments is not a true Array but instead an Array-like object, whereas the ...args rest parameter method will retrieve an actual Array - but it's one worth mentioning.
The actual passing through of these arguments happens when Function.prototype.apply is called, which allows a function to be called with a given value of this and a specified array of arguments. It's a sibling to the similar Function.prototype.call, which takes each argument to passed through as a separate parameter.
So in your example, you call test(1, 2, 3) and that executes the function that was returned by debounce(random, 1000). That function gets its arguments as an Array via the ...args rest parameter, and then passes that array through to the random function via func.apply(this, args).
To answer your question about passing a different set of parameters through, I recommend you try it and see. But the answer is yes: with this setup the debounced function is able to pass through any number of arguments.
Closures aren't directly relevant to how the arguments are passed through here. They are relevant in a different way, however, in that the timerId variable created when debounce is called is kept in a closure so that later attempts to call the debounced function will access it again, which is what allows the innards of this debounce implementation to clear the timeout it had created during its previous execution.

Pass more values to subscribe function of an observables

I would like to convert and replace all words in an array using a an object's method which returns an observable. The problem is that since the result is asynchronous, the value of result is overwritten incorrectly at the wrong index. If I had a synchronous function, I could have just simply call the function in a for loop. What should I do in this case?
for(let word in this.words){
var i = Object.keys(this.words).indexOf(word);
this.convertor.get(this.words[i].value).subscribe( (result) => {
this.words[i].value = result; //The value of i is incorrect
});
}
Since ES6 you can easily solve this by replacing var i = with let i =. That way you get a variable that has block scope, and so you get a different variable instance in each iteration of the loop.
The original answer works also when you don't have support for let:
You could solve this with a plain function that you bind an extra argument to:
this.convertor.get(this.words[i].value).subscribe( function (i, result) {
this.words[i].value = result;
}.bind(this, i));
.bind() returns a (new) function that will be like the function you apply bind on, but will pre-determine a few things for when that function is actually called:
this will then be set to what you pass to bind in the first argument. Contrary to arrow functions, old-fashioned functions normally get their this value by how the function is called -- that behaviour is not what you desire, and so it is a welcome feature of bind;
Some of the arguments can be fixed upfront. Whatever other arguments you pass via bind become the values of the first arguments of that function -- they are not determined by the actual call. In this case the value of i is passed, so the function will get that value as its first argument, no matter how it is called later.
Any other argument that is passed to the function at the moment of the call(back) will follow the previously mentioned arguments. In this case, the actual call will pass the value of result, and so the function should deal with two arguments: one provided by bind, the other by the caller.
This solves your issue as you can pass on the correct value of i to each of the functions without losing the value of this.
Another alternative could be forEach so you don't have to track the index and handle cleaning up the subscriptions with first() for example.
this.words.forEach((word, i) => {
this.obs$(word)
.pipe(
tap(v => (this.words[i].value = v)),
first()
)
.subscribe();
});
https://stackblitz.com/edit/static-iterable-value-from-obs?file=src/app/app.component.ts

When will an anonymous function be used?

For example below is an anonymous function that has been placed in parentheses so now the function can be stored as a variable and called on else where as seen in number 2, However how can script number 1 be called to run? How can it be identified if it has no name? And how to change an anonymous function to a defined function?
**Number 1**
(function() {
// Do something
})();
**Number 2**
(var funcName = function() {
// Do something
})();
funcName();
The first function is called immediately because it is followed by () which calls a function.
Then if you were to remove the () from around the var statement (which is an error):
The second function is also called immediately, for the same reason.
The value stored in funcName (which is called as if it were a function, so will cause an error if it is not a function) is the return value of the second function (and is defined by the code you represented as // Do something — the "something" needs to include "return a function").
How can it be identified if it has no name?
Names are only really useful for use in debuggers (where they are very useful in stack traces and the like). For identifying a function to call, you access them like any other object or primitive (via a variable, property, etc). A function declaration just creates a variable with a matching name in the current scope.
Yes, these are anonymous functions, but they are also functions that are being called / invoked immediately, and hence don't need names to be referred to later.
There are many uses for Immediately-Invoked Function Expression (IIFE), but one is to use functions to establish namespaces that do not pollute global

Explaining the benefits of using a high-order function in a simple English language

Consider this example, i need to know the benefits of using a high-order function as so:
function bind(func, object) {
return function(){
return func.apply(object, arguments);
};
}
I mean what's the problem with a simple function like so:
function bind(func, object) {
return func.apply(object, arguments);
}
This
function bind(func, object) {
return func.apply(object, arguments);
}
returns a result of func invocation. While bind should return a new function, which when called will be invoked in proper context (object).
The benefit in your example is that you get partial application:
Intuitively, partial function application says "if you fix the first arguments of the function, you get a function of the remaining arguments". For example, if function div stands for the division operation x / y, then div with the parameter x fixed at 1 (i.e. div 1) is another function: the same as the function inv that returns the multiplicative inverse of its argument, defined by inv(y) = 1 / y.
The practical motivation for partial application is that very often the functions obtained by supplying some but not all of the arguments to a function are useful; for example, many languages have a function or operator similar to plus_one. Partial application makes it easy to define these functions, for example by creating a function that represents the addition operator with 1 bound as its first argument.
In your example, there's three pieces of information:
which object
which method to call
which arguments to supply to that method call
Using your bind, you can decide on 1 and 2, while leaving 3 for later.
See Underscore for another example that generalizes partial application beyond just this.

why does the function passed to replace not have parenthesis

Why when passing a function to the last parameter of replace, does that function not take parenthesis?
From MDN:
function replacer(match, p1, p2, p3, offset, string){
// p1 is nondigits, p2 digits, and p3 non-alphanumerics
return [p1, p2, p3].join(' - ');
};
newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
If you added parenthesis, you would be evaluating the function expression named replacer.
Instead here you're passing a variable named replacer, which is a reference to the function. Instead of executing the function right away, you tell Javascript's replace to use it later, when it's called natively.
One metaphor I think of sometimes, is that you are handing over a gun for someone else to fire, you're not firing it yourself. replacer() means "fire the gun right away", whereas replacer means "here, use this to fire". The expectation here is that JavaScript's native replace() function will "load the gun" with bullets (parameters), and then fire it when ready.
Because when you use a function name with parentheses, f(), you are to call the function and using the results. When you use without parenthesis, f, if means you are using the function itself. If it helps, think of it as you want to use reference the code of the function, not the value it returns.
In your example, you are not calling the function replacer and passing the value to replace. You are passing a chunk of code called replaced to the function replace for the function replace to call it whenever it needs to.
In JavaSCript a function is an object like any other. It can be assigned to a variable, passed to a function, returned from a function, etc.
In this case the reference to replacer is being used as a variable here:
newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer);
The function itself is being passed into the call to replace. (Which will likely execute that function internally, at least under some condition.) If the parentheses were added like this:
newString = "abc12345#$*%".replace(/([^\d]*)(\d*)([^\w]*)/, replacer());
Then instead of passing the function itself as an argument, you'd be passing the result of the function as an argument. The result of that function appears to be a string. However, the function you're calling doesn't expect a string, it expects a function. (Passing it a string will likely fail when it tries to "execute" that string.)
It's a callback.
If you call replacer(), you'll be running the replacer function with no parameters.
In this case, replace function asks for a callback as the second parameter, and replace method will call the given callable parameter itself.
Think it like this, you can do something like this within replace function:
.replace(/([^\d]*)(\d*)([^\w]*)/, function() {
//You can write replacer's code here as a closure
});
Instead of defining a closure like this, you're telling replace function to call replacer function.
There is a little nuance here that might be difficult to grasp at first.
If you were to add parentheses, you would be indicating you want replacer to be invoked right then and there. That's not actually what you want to do.
replace is actually looking for a reference to a function, so you're actually passing in the function as an argument to replace. Internally, replace knows when and where to properly invoke replacer.
The reason is because replacer is a function pointer. Just as you can have pointers to instances of variables you can have pointers to functions. If parenthesis had been placed after replacer such as replacer() then replacer would be evaluated as the function itself. Instead what you are doing is passing a pointer to the function replacer which can then be called by the function replace.
In c++: A common use of an alternative of this pattern is function object / function pointers. In which the struct / object has the operator () overloaded to make it act like a function. But most languages have a version of these whether they be called functors, callbacks, function pointers or whatever.

Categories

Resources