In following example is a typical function which accepts three parameters:
function cook(a, b, c) {
// cooking stuff..
return[results];
};
Or as a property function, like this:
var myApp = {
handler: function(a, b, c) {
// actions
}
};
My question is how to call this function properly, if we want to pass
only two parameters, or even only one:
Like this:
cook(param1, param2); - myApp.handler(param1, param2);
Or we have to pass always the same number of parameters the function
accepts, regardless if they have data or not, like this:
cook(param1, param2, ""); - myApp.handler(param1, param2, "");
Also, what is the proper way if we want to pass the first and the third
parameters? Or only the second or the third parameter. I can't think
something other than this:
cook(param1, "", param3); - myApp.handler(param1, "", param3);
cook("", param2, "");
cook("", "", param3);
Is this correct and the only way to do it?
the best way as you describe your function would be using an object as a parameter
// function definition
function cook(object) {
//do stuff
return object.a + " " + object.b + " " + object.c;
}
parameters1 = {a:"paramA", b:"paramB",c:"paramC"}
cook(parameters1) // returns paramA paramB paramC
if you test those parameters in the function to handle cases where a, b or c might be null or undefined, you can then do
cook({a:"paramAonly"})
or
cook({a:"paramA", b:"paramB"})
"My question is how to call this function properly, if we want to pass
only two parameters, or even only one"
Ok. This question has multiple ways to interpret what you are asking, so I will give you one of those ways.
If you want to have a function that takes a varying number of parameters then you should use es6 spread operator like this
function (...args) { // the ... is the spread operator
return args
}
Now if you want to return always the first item in the parameters you do this:
function (...args) {
return args[0]
}
Lastly if you want to do something that is more flexible then you can offer this method:
function (... args) {
if(args.length === 3) {
return // you get the point?
}
}
Does this answer your question?
Do we have to pass always the same number of parameters the function ?
No, you don't have to pass all the parameters to a function, the arguments you don't set will be undefined
function cook(a, b, c) {
console.log(a, b, c)
};
cook('foo') // will console log 'foo undefined undefined'
What is the proper way if we want to pass the first and the third
parameters?
You were right on this one, although you would generally give undefined or null value as a parameter here rather than an empty string. If you want to ignore param2 but give param3 for example
cook(param1, null, param3)
Then you could test if all the parameters are properly set or not in your function with a more standard null or undefined value
Related
Very stupid question. For example I have a variable data and I have function DoSomething with two parameters par1 and par2. they are both optional parameters that would be null if I pass nothing. But I have only one variable data which I want to bound to the second parameter without touching first parameter. In different language I should write something like DoSomething(par2 = data) or DoSomething(par2: data) but all these examples will raise exception Uncaught SyntaxError: missing ). So what I did wrong?
If you have two optional parameters in JavaScript, just pass undefined to the first argument.
DoSomething(undefined, data);
undefined is the default value of arguments when they aren't passed in (DoSomething() would have both arguments be undefined) except when you set default values for optional arguments.
Another alternative is to pass in the arguments as an object, which requires changing the definition of the function and all calls to it: (?? is the Nullish coalescing operator
function DoSomething(args) {
const par1 = args.par1 ?? "default value";
const par2 = args.par2 ?? "default value";
}
// ....
DoSomething({ par2: "custom value" });
DoSomething({ par1: "custom value", par2: "customValue" });
Using TypeScript or JSDocs allows you to give guidance on how to send arguments in the IDE
You always can pass undefined or null as first parameter. SO it will be something like this:
DoSomething(undefined, data);
If you have multiple optional parameters, if you don't want to pass undefined.. you should use an object as the parameter.
// instead of DoSomething(param1, param2)
function DoSomething(param = {}) {
const { param1, param2 } = param;
//..do something with param1 and param2
}
DoSomething({ param2: 'somevalue' })
If you consider using typescript, it's even better because you can add the
type to the param.
First of all, if you don't pass a parameter, it would be undefined, not null.
If you want to skip the first parameter, you still have to pass it in, just pass it in as something falsy (assuming your doSomething function handles that case).
const data = 'foo';
function doSomething(param1, param2) {
if (param1) console.log(param1);
if (param2) console.log(param2);
}
doSomething(null, data);
If you a similar functionality to Python, you can take in a single parameter, which is an object.
const data = 'foo';
function doSomething({ param1, param2 }) {
if (param1) console.log(param1);
if (param2) console.log(param2);
}
doSomething({ param2: data });
I'm trying to write some js function's validation.
Idea: I have checking function, passing to it checked function object, here make sure that all right (or not). I don't want to pass arguments separately, only function object.
How can i reach this?
For now i forced to be content with two parameters for checking function - func obj and func arguments
That is what i want:
function checkFunction(func) {
console.log(func.name);
console.log(func.arguments);
// validate something
}
function checkedFunction(a, b, c) {
checkFunction(checkedFunction...);
// do something
}
That is what i have now:
function checkFunction(func, args) {
console.log(func.name);
console.log(args);
// validate something
}
function checkedFunction(a, b, c) {
checkFunction(checkedFunction, arguments);
// do something;
}
I have a lot of my code inside an object literal and there are a couple functions where I want to be able to pass the functions arguments for the parameters but I can't figure out how to do that.
Here is an example of my object..
var test = {
button: $('.button'),
init: function() {
test.button.on('click', this.doSomething);
},
doSomething: function(event, param1, param2) {
console.log(param1);
console.log(param2);
}
};
So when the button is clicked and it calls the function doSomething I want to pass in arguments for param1 and param2.
Something similar to this maybe, but this does not work.
test.button.on('click', this.doSomething('click', 'arg1', 'arg2'));
Any ideas, or am I going about this the wrong way?
The jQuery.proxy() function seems to be exactly what you need. Have a good read at the docs and see if they make sense to you. For your specific example,
var test = {
button: $('.button'),
init: function() {
test.button.on('click', $.proxy(this.doSomething, null, 'arg1', 'arg2');
},
doSomething: function(param1, param2, event) {
console.log(param1);
console.log(param2);
}
};
In this example, the parameters to $.proxy are:
this.doSomething - The the function to call
null - The context in which the function will be called. By supplying null, we are saying to use its 'normal' context.
arg1 - The value of param1 formal parameter of the called function
arg2 - The value of param2 formal parameter of the called function
Since the click callback supplied the final parameter (event), that is already provided and doesn't need to be additionally or explicitly declared. The jQuery.proxy() when passed additional parameters passes those at the front of the formal parameter list and any remaining parameters implicitly supplied are passed at the end. So if we a function that looks like:
var f = function(a, b, c) {
console.log(a, b, c);
};
and invoke it through a proxy:
var p = $.proxy(f, null, 2, 3);
p(1);
The value of a, b and c that are logged will be 2,3,1.
This question is also extremely close to this one.
How can I pass arguments to event handlers in jQuery?
I'm studying apply and I am trying to understand why the code I am studying only passes one parameter to apply.
I first define Quo:
var Quo = function(string) {
this.status = string;
};
Next I define get_status:
Quo.prototype.get_status = function() {
return this.status;
};
I define statusObject:
var statusObject = {
status: 'yo!'
};
And this is where I am lost:
var status = Quo.prototype.get_status.apply(statusObject);
// status is 'yo!'
According to the documentation "Apply Calls a function with a given this value and arguments provided as an array." You can see in the case, using apply I pass only a single parameter, which I believe is defining "this". Can you clear up what exactly is happening in this method, why apply is necessary, and why in this case I can only pass one param to the method, when it states two are needed. Thank you.
apply sets the context of the function being applied to the object provided in the first parameter.
var o;
function baz(a, b, c) {
//do stuff
}
o = {
foo: 'bar'
};
baz.apply(o);
//this is o
//a is undefined
//b is undefined
//c is undefined
If an array is passed as the second parameter, the parameters will be set based off the values in the array:
baz.apply(o, [1,2,3]);
//this is o
//a is 1
//b is 2
//c is 3
The second parameter in apply is optional, however call is typically used for settings context:
//these do the same thing
baz.call(o);
baz.apply(o);
//this is how they're different
baz.call(o, 1, 2, 3);
baz.apply(o, [1, 2, 3]);
It doesn't state that two are needed:
fun.apply(thisArg[, argsArray])
notice how argsArray is in brackets, it is optional.
What is happening on your call, is that your statusObject is passed as the this argument to your get_status function.
This means that when get_status executes and does return this.status it is in essence returning statusObject.status.
Apply is useful for many reasons, one of which is to invoke methods dynamically. I can pass the string name of a method in the object to be invoked like so:
methods = {
init: function(message) {
alert(message);
}
};
function executeFunc(method) {
methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
}
//now I can call like this:
executeFunc('init', 'Hey there, this is a message');
An example of this can be found in my jQuery Plugin skeleton on GitHub
apply takes one argument, the object to use as this, followed by the arguments if any.
If the function takes no arguments, e.g. you have function f() { ... }, you don't need to pass any arguments, so you can call f.apply(someObject);.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Is it possible to send a variable number of arguments to a JavaScript function?
I can use arguments to get a variable number of arguments within a function, but how can I pass them to another function without knowing its prototype?
function show(foo, bar) { window.alert(foo+' '+bar); }
function run(f) { f(arguments); } // not correct, what to do?
run(show, 'foo', 'bar');
Note: I cannot guarantee the number of arguments needed for the function f that is passed to run. Meaning, even though the example shown has 2 arguments, it could be 0-infinite, so the following isn't appropriate:
function run(f) { f(arguments[1], arguments[2]); }
The main way to pass a programmatically generated set of arguments to a function is by using the function's 'apply' method.
function show(foo, bar) {
window.alert(foo+' '+bar);
}
function run(f) {
// use splice to get all the arguments after 'f'
var args = Array.prototype.splice.call(arguments, 1);
f.apply(null, args);
}
run(show, 'foo', 'bar');
You can in fact do this with apply, if I understand your question correctly:
function show(foo, bar) { window.alert(foo+' '+bar); }
function run(f, args) { f.apply(null,args); }
run(show, ['foo', 'bar']);
you need to use the apply function.. here is how u do it:
function variableFunction1()
{
alert("variableFunction1 arguments length: " + arguments.length);
// calls second varargs function keeping current 'this'.
variableFunction2.apply(this, arguments);
}
function variableFunction2()
{
alert("variableFunction2 arguments length: " + arguments.length);
}
variableFunction1('a','b','c');
Demo
In your example to pass variable arguments to show this works
function show(foo, bar) { window.alert(foo+' '+bar); }
function run(f) { f.apply(null, Array().slice.call(arguments, 1)); }
run(show, 'foo', 'bar');