I'm using a single structure dynamically for many function as shown below:
Parent[funcName](data, function(err) {
// further operations
});
The variable "data" in the function have 0, 1, 2 or 3 as per the function requirement. It works fine when single argument is passed in "data" but if more than 1, it shows error - "more argument are expected".
So how can I pass multiple arguments by using single variable? Is there any work around?
You can use the spread operator
Parent[funcName](...data, function(err) {
// further operations
});
where data is the array of all the parameters you have passed.
Just make use of the arguments object:
function myFunction() {
for (var i = 0; i < arguments.length; i++) {
console.log(arguments[i]);
}
}
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments
or this way:
function foo(...args) {
return args;
}
foo(1, 2, 3); // [1,2,3]
greetings
Related
I am attempting to write a function that takes an array and another function as an input. The only thing I know about the supplied function though is that it either
takes a single number argument and returns a new number or
takes an array of numbers and returns a new array of numbers.
In my function, I want to check whether it's the first or second case to determine whether or not to call the supplied function with Array.prototype.map().
So with these two functions...
var unknownFunction = function( unknownInput ) {
//Does stuff with input
//returns number or array of numbers...
return someValueOrValues
}
and
var mainFunction = function( anArray, preFunction ){
// SOME CODE TO CHECK IF ARG NEEDS TO BE NUMBER OR ARRAY
// ...
// ...
**ANSWER WOULD FIT HERE**
if( argIsNumber === true ){
// function takes NUMBER
anArray = anArray.map( preFunction )
}else{
// function takes ARRAY
anArray = preFunction(anArray)
}
// DO STUFF WITH ARRAY AFTER USER FUNCTION HAS MADE IT'S MODIFICATIONS
// ...
// ...
// ...
return anArray;
}
is there any way to poke inside the first function to figure out how best to call it?
Since JavaScript is a dynamically-typed language, function's input parameters have type once some calls it with some argument.
One elegant and possible approach is adding a property to the whole given function to hint the input parameter type:
var func = function() {};
func.type = "number"; // a function decorator
var mainFunction = function(anArray, inputFunc) {
if(typeof inputFunc != "function") {
throw Error("Please supply a function as 'inputFunc'!");
}
switch(inputFunc.type) {
case "number":
return anArray.map(preFunction);
case "array":
return preFunction(anArray);
default:
throw Error("Type not supported");
}
};
mainFunction([1,2,3], func);
When you work with dynamically-typed languages you need to think about coding using convention over configuration and/or using duck typing. Type safety provided by strongly-typed languages is replaced by a good documentation.
For example:
Provide a function as second parameter with a type property to tell
the mainFunction what's the expected type of the predicate
function.
I would use the try-catch approach but test the actual functions, and if one fails to try the next one.
Let's say these are your functions that are passed in as your unknow function. They each only modify a number by adding 1 to it.
function onlyTakesNumber(num) {
return num + 1;
}
function onlyTakesArray(arr) {
return arr.map(num => num + 1);
}
Now, here is your main function. The reason for the additional map inside of the try is to test to make sure you didn't get a string back if an array was passed to the onlyTakesNumber function. The additional test map will again reveal if the code needs to hop into the catch.
var mainFunction = function (anArray, preFunction) {
try {
// the map on the end checks to make sure you did not get a string back
anArray = preFunction(anArray).map(test => test);
}
catch (e) {
anArray = anArray.map(preFunction);
}
// Do whatever else with anArray
return anArray;
};
console.log(mainFunction([1, 2, 3], onlyTakesArray)); // [2, 3, 4]
console.log(mainFunction([7, 8, 9], onlyTakesNumber)); // [8, 9, 10]
Here is a JSFiddle you can test this on
The shortest answer is: "you can't".
I came across a weird code which I didn't understood. It would be great if I get explanation.
function forEach(array, action) {
for (var i = 0; i < array.length; i++) {
action(array[i]);
}
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
forEach(numbers, function (number) {
sum += number;
});
console.log(sum);
How the function got passed as parameter ? and how the inner function is getting that number.
In JavaScript, functions are what's called first class citizens (that's not necessarily true for other languages), that means that functions can be treated as data, you can pass functions as arguments, return functions from other functions, and create functions and assign them to variables.
Here's a very simple example:
function callWithoutParams(fn) {
return fn(); // fn is the passed function.
}
let rand = callWithoutParams(Math.random); // Passing Math.random as a function.
callWithoutParams(() => console.log(42)); // Passing anonymous function
Array.prototype.forEach() accepts a function as an argument, and runs it on each element in the array. So a simpler example is:
[1,2,3,4,5].forEach((element) => console.log(element)); // outputs 1-5 in order.
In javascript, everything is an object, including function.
For simplicity, check this example:
var func = function(number){
console.log(number);
}
var arr = [1,2,3,4,5];
function foreach(data, callback){
for(var i = 0; i<data.length; i++){
callback(data[i]);
}
}
foreach(arr, func);
In JS, you can assign function to a variable. This is called as Function Expression. So it acts as a normal variable, just that its type is object.
This allows us to pass function as a parameter.
Now your second question, how the inner function is getting that number.
in your code, action(array[i]); is passing value as a parameter, so
function (number) {
sum += number;
}
here number is array[i].
I've encountered some code that I'm having trouble fully understanding. The principles seem clear enough, but I'm having some difficulty with the second argument that's declared in the forEach function call. Clearly the anonymous function is passed into forEach via the action argument, but how exactly does it work once inside the for loop?
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
forEach(numbers, function(number) {
sum += number;
});
console.log(sum); // 15
I think what confuses me most is that the syntax of the anonymous function doesn't seem compatible with action(array[i]) - I mean, I understand that sum acquires each value of the array in turn, but if the function "replaces" the action argument, how and where does the (array[i]) part fit in?
Let me rewrite that code in a more explicit way:
function forEach(array, action) { //1st parameter is an array, the 2nd is a function
for (var i = 0; i < array.length; i++)
action(array[i]); //The function is used, with each element of the array as parameter
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
var myFunction= function (number) { //I declare a function which receives a number
sum += number; //and adds it to sum.
}
forEach(numbers,myFunction); //I call the forEach function using the
// variables I previously created as parameters
console.log(sum);
In javascript when you define a variable you write:
var x = 0; // here you reserve an object
And when you define a function also you reserve an object. Javascript deal with functions as objects and you can assign it to any variable:
var x = function(number){ sum +=number; };
forEach (numbers, x(number) );
And about the confused syntax, Anonymous functions are functions that are dynamically declared at runtime. They’re called anonymous functions because they aren’t given a name in the same way as normal functions.
So to call an Anonymous function you follow this syntax:
// call
function (param1, param2, ...){
// function body
}
if you want to call it again either you should repeat the code above or declare a function without calling it and save it on variable where you can call it many times:
// declaration
var x = function(param1, param2, ...){
// body
};
// call
x(p1,p2,....);
I am working with a very poorly documented javascript API, and need to write callback functions where the arguments have not been documented. As an opening step, I need to inspect what gets passed in. If I know that there's only one input I can set the callback function to be
function( stuff ){
console.log(stuff);
}
and work from there. Is there an elegant way to inspect inputs when I don't know how many there are? I could do something like
function(a,b,c,d,e,f){
console.log(a)
console.log(b) // is this undefined?
console.log(c) // how about now?
....
console.log(f) // if this isn't undefined I need to do it again with more args
}
and it will work fine, but it's pretty ugly. Is there a simpler way to find out how many argumetns have been passed to a function?
Loop the arguments object:
function f(){
for(var prop in arguments) {
console.log(arguments[prop]);
}
}
f(1); // logs 1
f(1, 2); // logs 1, then 2
As arguments is an array-like object, you can also iterate it with a regular for loop, based on its length property:
for(var i=0; i<arguments.length; i++) {
console.log(arguments[i]);
}
It looks like you are after arguments, which gives you an array of the arguments passed to the current function:
var f = function() {
console.log(arguments);
}
f(1, '2');
f(1, 2, 3, 4, 5);
(Fiddle)
Use arguments
function unknown() {
for (var i=0;i<arguments.length;i++) {
console.log('arg '+i+' : ',arguments[i]);
}
}
unknown(123, 'test', [1, 2, 3]);
arg 0 : 123
arg 1 : test
arg 2 : [1, 2, 3]
I want to create a function in javascript with a variable amount of arguments. The next example is how I want to call this function:
myFunction(1,2);
myFunction(1,2,3);
myFunction(1,2,3,4);
myFunction(1,2,3,4,5);
myFunction(1,2,3,4,5,6);
Anyone knows how to define this function?
You can access the arguments by their ordinal position without the need to state them in the prototype as follows:
function myFunction() {
for (var i = 0; i < arguments.length; i++)
alert(arguments[i]);
}
myFunction(1, 2, "three");
>>1
>>2
>>three
Or if you really are passing in a set of semantically related numbers you could use an array;
function myFunction(arr) { ... }
result = myFunction([1,2,3]);
Latest update
Rest parameters are supported in all new browsers.
Check here for details
The rest parameter syntax allows us to represent an indefinite number of arguments as an array, which you can pass it to other functions too.
function myFunction(...data){
console.log(...data);
myOtherFunction(...data);
}
myFunction(1,2,3); //logs 1,2,3
myFunction([1,2,3]); //logs [1,2,3]
Use the 'arguments' variable like this :
function myFunction() {
alert(arguments.length + ' arguments');
for( var i = 0; i < arguments.length; i++ ) {
alert(arguments[i]);
}
}
Call the methods as you did before
myFunction(1,2);
myFunction(1,2,3,4,5,6);
Just refer to the arguments array.
https://developer.mozilla.org/en/JavaScript/Reference/functions_and_function_scope/arguments
If an argument is not present, use the default. Like this...
function accident() {
//Mandatory Arguments
var driver = arguments[0];
var condition = arguments[1]
//Optional Arguments
var blame_on = (arguments[2]) ? arguments[2] : "Irresponsible tree" ;
}
accident("Me","Drunk");
As an add-on: You can assign values to the unnamed function parameters, as in (german wiki)
arguments[0] = 5;