Call a function with 'arguments' as separate arguments - javascript

I'm trying to pass the arguments variable of a function as separate arguments to another function. I tried this:
function call_function(func) {
func(arguments);
}
However, call_function(someFunction, 123, 456) actually calls someFunction([someFunction, 123, 456]). Regardless of the function itself being passed, it is passed as an Arguments object/array-like thing, but I'd rather call the function in this case as someFunction(123, 456).
What I also tried is: func(Array.prototype.slice.call(arguments, 1)) to remove the function (first argument), but obviously this actually returns an array, i.e. it passes the array as the first argument to the function.
How could I code call_function so that a call like call_function(someFunction, 123, 456) results in someFunction(123, 456) being called?

You can use the apply function to call a function with the array as arguments.
https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/apply

Related

can please someone explain the working of bind function for this example from eloquent

isInSet requires two arguments, but binds passes only theSet as first argument. I am not able to figure out how bind method works in this case
function isInSet(set , person) {
return set.indexOf(person.name) > -1;//checks for existence of person.name in theSet
}
console.log(ancestry .filter(function(person) {
return isInSet( theSet , person) ;
}) ) ;
// ! [{ name : " Maria van B r u s s e l " , ...} ,
// { name : " Carel H a v e r b e k e " , ...}]
console.log(ancestry.filter(isInSet.bind(null, theSet))) ;//**how does this work?**
// !... same result
bind() creates a new function from the function that it is called on. It sets the this keyword in the newly created function to be the first argument that you pass it (if null is passed, then it does not overwrite the default this keyword). You can also pass in extra arguments to bind() and if you do, they will always be inserted into the new function. So for instance, let's say you have a sum function that takes 2 arguments.
function sum (a, b) {
return a + b;
}
Now we could create a new function from this using bind() and always pass in one argument.
var boundSum = sum.bind(null, 2);
This will always bind 2 as the first argument in the sum() function. Now anytime you call that boundSum() function, it will only take one argument, as the 2 is already bound.
boundSum(3); // <-- this would return 5
Your example is using a similar principle. Because you are calling isInSet.bind(null, theSet) it is always binding theSet to the first parameter passed in the isInSet function. However, it is still missing the second parameter. The reason why it works is because you are putting that inside of an ancestry.filter() function. filter() essentially loops over an array and passes each element to the function inside of it (check the docs). So therefore, each element in the ancestry array is getting passed to that bound function, which makes it the second parameter of isInSet().
Read the text from the book a few times and compare the unbound and the bound version.
Calling .bind() on a function, return a new function, with some of the arguments already filled in. The isInSet function, expects two parameters: the set to filter, and a person having a name.
The .filter() method of an array, expects one parameter, namely the function to which each element of the array has to be sent to.
So when you look to the unbound version, you see that the filter function used, just returns isInSet(theSet, person).
So to make the two compatible, we .bind() to create a new function with only one parameter left (namely 'person'), that is bound to theSet. So every time this new function returned by bind gets called, it will use theSet as it's first parameter and will expect only one parameter, 'person'.
Here, person, the second parameter of the original isInSet function we didn't bind, is used as the first and only parameter of the bound function.
So we have exactly what we need after using the bind. A function that will take a 'person' as a parameters and will always look inside the same array (theSet).
If you read the docs for .bind(), you see that it accepts a variable list of arguments. The first argument is the 'this' argument. So if you have a function that uses 'this' inside it and you want to bind it to eg. an object, you can use the 1st parameter. Eg. myFunc.bind( objectToCallUpon, firstArg, secondArg );
Since we don't actually use the 'this' argument in the isInSet() function, we just pass 'null' as the 'this' value.
All the other parameters used are the arguments of isInSet you want to make 'fixed'. Since we want the first parameter to always be theSet, we bind that value.
If the isInSet function would accept two parameters, you would use:
isInSet.bind( null, theSet, secondParameter );

Javascript: How to get callback's parameters

I'm trying to somewhat replicate the functionality of forEach so that I can understand it better. In forEach you can pass it in an anonymous function with a parameter 'item' and then it would give you the items in the array. So how is this done exactly? Below I have a function print where I call another function a with an anonymous function as parameter. So how can I extract the parameter called 'param' from the anonymous function and use it in a's definition.
function print() {
var param = 'param1'
a(function(param) {
console.log('execute a')
})
}
function a(fn) {
//how can i access the fn's parameter list here?
//execute fn and do something with its parameter
fn()
}
print()
What I'm trying to accomplish: Run the function "a" and execute the anonymous function passed into it along with its parameters
You're completely misunderstanding parameters.
Your callback is a function. Its parameters are passed by the code that calls it (in a()), just like any other function.
If you want to pass a parameter to a(), you should pass it like any other parameter.
The fact that your callback's parameter happens to have the same name as a local variable is completely irrelevant.

Javascript arguments object

I am having a hard time understanding the arguments object. In this code, what function would arguments be looking at?
getAjax('get_info', 'java_array', realVarName, cld.listArray, 0, '',
'no_restrict', function() {
show_list(arguments[0], sld);
if (typeof(postFunc) == "function") {
postFunc();
}
});
'arguments' is an inherit variable with any function. It contains all the parameters passed to a function. For instance, a function definition may not list any parameters, however an invocation could include 'n' parameters on it. The function could then still access all of them through the arguments array.
The arguments object is an Array-like object corresponding to the arguments passed to a function.
In your code the arguments[0] will primarily be undefined
First off, arguments is an object that represents the set of arguments passed to the current function. It exists automatically inside of every function. You can read more about it here on MDN.
So, in your case, arguments[0] will be the first argument that getAjax() passes to the callback you passed into it as the last argument when you called getAjax(). So, it depends upon the internal behavior of getAjax() which you do not show us.
Let's walk through how your code works:
You make a function call to getAjax() and pass it a number of arguments.
One of those arguments is a callback function (the last argument).
When getAjax() is doing its job, it will, at some point, call that callback function.
When it calls that callback function, it can pass that callback some arguments.
Within that callback function the arguments object will represent whatever arguments were passed to it by getAjax().
So, when (in that callback function), you then get arguments[0] and pass it to show_list(), you will be passing whatever the first argument was that getAjax() passed to your callback.
You could rewrite your code without using the arguments object like this by just declaring a named argument for your callback:
getAjax('get_info', 'java_array', realVarName, cld.listArray, 0, '',
'no_restrict', function(obj) {
show_list(obj, sld);
if (typeof(postFunc) == "function") {
postFunc();
}
});
In this alternate implementation, you name the first argument to the callback function to be obj and use it directly rather than using arugments[0]. Both your implementation and this produce the same result.
It is generally better to use named arguments (like the obj in my alternate implementation) when you know what arguments are going to be passed to a function as this makes the code more self documenting. But the arguments object can be particularly useful when you don't know how many arguments are going to be passed to a function or when you want to pass whatever arguments were passed to your function to some other function (forwarding or proxying).

Bounded call of call function

I am curious how bounded call function works inside in Javascript. The confusing example:
Number.call.bind(Array)(undefined, 1, 2)
Output:
[1, 2]
Indeed, instead of Number I can write any function and that will be ignored. My assumption is at some moment Array is called as a constructor function and 1 and 2 are passing as parameters. My question is what inside of call function leads to such a strange behavior?
Thanks.
call is not much different from any other function (expect it can set this somehow). Here is a pseudo-code pseudo-version of call:
function call(thisArg, ...args) {
let boundThis = this.bind(thisArg);
return boundThis(...args);
}
So, all it really does is setting this of the function to the fist argument passed and then passes the remaining arguments to the function.
call.bind(Array) binds this inside call to Array, i.e. it "fixes" the function to which .call is applied to Array, meaning it will now always call Array. So you essentially have
let boundThis = Array.bind(thisArg);
return boundThis(...args);
which is basically Array(...args).
The first parameter in Function.prototype.bind() is the "thisArg" with which the bound function is called. Since the bound function in your example is Function.prototype.call(), that effectively returns a bound version of call() such that it is equivalent to Array.call(). The first argument for call() is the "thisArg" (yet again) with which the called function is called, and the rest are the parameters passed into the function. So now we're at Array(1, 2), and that returns your output.
What you're doing, via bind, is no different from:
Number.call.call(Array, undefined,1, 2);
The above sends four parameters to the call on the right, the first of which is the context to call the call on the left. Thus, after the call on the right finishes, the code factors to:
Array.call(undefined,1, 2);
Which factors to:
Array(1, 2);
Notice that Array is actually the function being called.
It could be any other function rather than a constructor:
Number.call.call(alert, window,"hello world");

Understanding the apply method example in functional programming in Eloquent JavaScript

I am reading the Eloquent JavaScript and I got to Functional programming (chapter 6). I am confused by the following example:
show(Math.min.apply(null, [5, 6]));
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
*Note: The show() simply prints out the output to the console on the Eloquent JavaScript website.
I don't get how the negate() function is related to the code within show(). Where is the negate() function called? I don't see that it was used anywhere in that example, or am I wrong?
The code given contains two examples. Every function has an apply method. In the first example, Math.min's apply method is used to call Math.min with the argument list [5,6]. The second example should be viewed in contrast to the preceding example in which negate is defined as
function negate(func) {
return function(x) {
return !func(x);
};
}
In that example, negate(func) returns a new function of one argument that calls func with that single argument, negates the result, and returns it. What happens if func expects more than one argument, though? That's what this example covers.
function negate(func) {
return function() {
return !func.apply(null, arguments);
};
}
In this definition, negate(func) returns a new function of an arbitrary number of arguments that calls func with the list of provided arguments, negates the result, and returns it.
That part of the book was to explain that some functions take multiple parameters, so you must call the func parameter with .apply() instead of just func(x).
The first example used NaN, which accepts one parameter. That's why it worked to use:
return !func(x);
But some functions, like Math.min, accept several parameters. Technically, when using negate, you don't know what function will be passed, and what arguments will be passed. Therefore, you can't hardcode in x being passed to func. Using .apply(), you can pass the original arguments, arguments, to the func call.
Reference:
apply: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Function/apply

Categories