Javascript: passing multiple arguments as a single variable - javascript

is it possible to pass multiple arguments using a single variable? For example, if I wanted to do something like:
function foo(x,y){
document.write("X is " + x);
document.write("Y is " + y);
}
var bar = "0,10";
foo(bar);
The example above is an simplified example of what I was trying to do. It doesn't work (because the "bar" is detected as a single argument). I know that there are easier ways to implement this using arrays.
So, I ask this question mostly out of curiosity - is it possible to get the "bar" variable to be detected as not one, but 2 arguments?
Thanks!

function foo(thing) {
document.write("X is " + thing.x);
document.write("Y is " + thing.y);
}
var bar = {x:0, y:10};
foo(bar);

What you're asking for is impossible. If you want to pass multiple values in a single argument, use an Array or an Object. If you really must use a string, you'll have to call split() to break the argument string into an array.

function Add (a, b, c) {
return a + b + c;
}
var nums = [1, 2, 4];
var sum = Add.apply (null, nums);
variable-length argument list:
function Add () {
var sum = 0;
for (var i = 0; i < arguments.length; i++) {
sum += arguments[i];
}
return sum;
}
var n = Add (1, 2, 3, 4, 5);
Reference: apply method (Function object)

Sure, this is common to pass an object for options
function foo(options){
//...
}
then you can pass in anything...
var opts = {};//create an object
opts['x'] = 5;//set whatever properties you want
opts['y'] = 23;
opts['border'] = 3;
foo(opts);//pass 1 argument, with as many values as you want
Often these are defined inline, especially if the values are not needed outside of the method call.
foo({'x':5,'y':23,'border':3});

Not really.
You could do:
window.foo.apply(window, bar.split(','));
(Apply lets you pass an array of arguments instead of each argument separately)
… but the phrase "ugly" comes to mind.

You may use this:
var bar = [0,10]; // creates an array
foo(bar);
function foo(arg){
document.write("X is " + arg[0]);
document.write("Y is " + arg[1]);
}

No, but you could pass a an array or object:
function foo(options){
document.write("X is " + options.x);
document.write("Y is " + options.y);
}
var bar = {x: 0, y:10};

No, it's not possible. You could put two arguments in an array, but an array is still one variable. Then you would need to rewrite the function to accept one variable, and treat it as an array, like this:
function foo(x){
document.write("X is " + x[0]);
document.write("Y is " + x[1]);
}
Basically, a function accepts variables as arguments and, no matter what kind of variable you pass it, each variable is still only one variable - there's no way to get a single variable to be recognized as multiple arguments. An array is one variable, a JSON object is one variable, etc. These things have multiple parts to them, but they're encapsulated by a single variable.

How about? (For ES6+)
function foo({x, y}){
document.write("X is " + x);
document.write("Y is " + y);
}
and call it with:
foo({x:10, y:5})
There is a downside to using a single structured argument over multiple arguments, and that is with multiple arguments you can use /** in may IDEs to generate a method header which will display an #param for each argument.
But if you only have one argument then you will lose the niceness of a description for each argument and hence less useful intelli-sense in the IDE as it wont pick up the docuemntation of the structure's properties.
/**
* Do stuff
* #param {*} param0 - A structure containing the blah, blah blah data
*/
function foo({x, y}){
instead of..
/**
*
* #param {*} x - The value for blah
* #param {*} y - the value for blah-blah
*/
foo1(x, y){

To directly answer your question, no. It's worth noting that the way you have bar defined it's only one value, a string containing "0,10".

function myFunction(a,b){
//do stuff with a and b here
}
myFunction(1,'text')
or...
<a onClick="myFunction(1,'text');"
There's an article on the issue here.

Related

How does Javascript define the arguments in this function

I am very new to Javascript and I am trying to figure out how array iteration works. In this code below, could somebody please explain to me how Javascript understands what the arguments in the function relate to -namely: value, index,array. Are these reserved keywords. If 'value', swapped positions inside the parantheses with 'index' would the function still work? Maybe i'm asking how or where have these arguments been defined?
var txt ="";
var numbers =[45,4,56,8, 32];
numbers.foreach(myFunction);
function myFunction (value,index,array) {
txt= txt + value + "<br>";
}
You can define your function parameters in Two Ways
Positional
In positional it does not matter what is the name of your parameters because parameters are assigned by their position not by their name so you can change myFunction(value, index, array) to myFunction(a, b, c) and It still works because their positions matters not their name.
Named
There is another way to defined function parameters where the position does not matter but naming them does.
For example a subtract function can be defined in two ways
function subtract({ firstNumber, secondNumber } = {}) {
return firstNumber - secondNumber;
}
which is Named and can be called with both subtract({ firstNumber: 10, secondNumber: 5 }) and subtract({ secondNumber: 5, firstNumber: 10 }) and still both results are the same but you have to remember the names.
But if defined in Positional:
function subtract(firstNumber, secondNumber) {
return firstNumber - secondNumber;
}
The two subtract(5, 10) and subtract(10, 5) yields different results because their position matters.

How to use apply with currying?

I have code that is using currying to get the average on an array that results from concatenating two arrays: an n size array and an m size array.
var avg = function(...n){
let tot=0;
for(let i=0; i<n.length; i++){
tot += n[i];
}
return tot/n.length;
};
var spiceUp = function(fn, ...n){
return function(...m){
return fn.apply(this, n.concat(m));
}
};
var doAvg = spiceUp(avg, 1,2,3);
console.log(doAvg(4,5,6));
In this line return fn.apply(this, n.concat(m));, I don't understand why do we need to use apply. What is the object we are binding with the average function and why does just normal calling (return fn(n.concat(m));) not work?
In that example, this is not that important. It would also work if instead of this you would pass an empty object instead. It's just an example on how to use apply.
What you need to focus is on the second parameter n.concat(m). They key concept here is that passing an array as a second argument you are calling that function (fn) passing each value in the array as an argument.
About your second question: no, it won't work because fn expects several arguments (one per value to calculate the average) while by doing return fn(n.concat(m)); you are just passing one argument, an array containing all values
Maybe you would understand it better with a simpler example:
function sum3params(a,b,c){
return a+b+c;
}
console.log(sum3params([3,4,2])) // won't work
console.log(sum3params.apply(this, [3,4,2])) // will work ('this' is not important here)
For this use case, it does not. But consider the following:
var foo = {
bar: 3
};
var addBar = function(a, b) { return a + b + this.bar };
foo.add3AndBar = spiceUp(addBar, 3);
foo.add3AndBar(1); // 7
Using apply means that your spiceUp function can be applied to methods as well as normal functions. For more likely example, consider partially applying when defining a method on a prototype:
const ENV = "linux";
DoesSomePlatformSpecificStuff.prototype.getPath = spiceUp(ENV);
apply also will spread the gathered array of arguments back out into positional arguments which can also be done like so:
return fn(...n.concat(m));
Which can be simplified as
return fn(...n, ...m);
Which is equivalent to
return fn.apply(undefined, n.concat(m));

Unfamiliar use of square brackets in calling a function

In the middle of this page, I find the code below.
var plus = function(x,y){ return x + y };
var minus = function(x,y){ return x - y };
var operations = {
'+': plus,
'-': minus
};
var calculate = function(x, y, operation){
return operations[operation](x, y);
}
calculate(38, 4, '+');
calculate(47, 3, '-');
Now while I can trace how it works, I've never seen this use of square brackets before. It certainly doesn't look like it's creating an array or referencing a member of an array. Is this common? If so, where are some other examples?
It is a dictionary access, which is like an array, but with a key instead of a numeric index.
operations['+'] will evaluate to the function plus, which is then called with the arguments plus(x,y).
It's called bracket notation.
In JavaScript you can use it to access object properties.
here operations is an object where the symbols + and - refers to two functions.
operations[operation] will return a reference to function plus where value of operation is + and then the following () will invoke the function
operations is an object and when you do operations[property] you will get the associated function and then you are passing the operands as x and y.
operations['+'] is function (x,y){ return x + y } which is plus
operations['-'] is function (x,y){ return x - y } which is minus
My JavaScript book says that object properties need be named with arbitrary names. But '+' and '-' are not names. From the original question, it is inferred that object properties just need be keyed, not named.

Is there a JavaScript equivalent for C# 'params'?

I need a method that can have an arbitrary number of parameters. In C# we have the params statement. Do we have anything similar in JavaScript?
There is the arguments collection, which contains all arguments passed to the function.
There is a) no need to specify "optional" arguments in the function signature and b) any function accepts any number of parameters.
function foo() {
console.log(arguments);
}
foo(1,2,3,4); // logs [1, 2, 3, 4]
Likewise, there is no need to supply "required" arguments in a function call:
function foo(a, b, c, d) {
console.log(arguments);
}
foo(1,2); // logs [1, 2]
Any argument named in the signature but not supplied in the function call will be undefined.
Note that arguments behaves like an Array, but technically it isn't one. For example, you can call arguments[0], but you can't call arguments.slice(). What you can do to get around this is using the Array prototype:
Array.prototype.slice.call(arguments, 1, 2);
The so-called rest parameter ... is a new (ES6+) addition to the language and makes working with variadic functions more comfortable. #ArunCM's answer explains it.
I know this thread is too old but I believe something is missing here.
There is Rest parameter (introduced in ECMAScript 6) which will allow us to represent an indefinite number of arguments as an array.
It always returns an array. Which means even in defensive JavaScript land, it’s ok to do things like check .length of rest without guards.
Syntax :
function(a, b, ...theArgs) {
// ...
}
There are three main differences between rest parameters and the arguments object:
rest parameters are only the ones that haven't been given a separate name, while the arguments object contains all arguments passed to the function
the arguments object is not a real array, while rest parameters are Array instances, meaning methods like sort, map, forEach or pop can be applied on it directly;
the arguments object has additional functionality specific to itself (like the callee property).
Additional reading : Spread
function f(x, ...y) {
// y is an Array
return x * y.length;
}
console.log("Expected result : 3*2 = 6 & Actual result : " + f(3, "hello", true));
console.log("Expected result : 3*4 = 12 & Actual result : " + f(3, "a", true, "b", 1));
//here we are not passing anything to "y" but its still safe to check .length of "y" because it always return an array.
console.log("Expected result : 3*0 = 0 & Actual result : " + f(3));
Yes. arguments.
function concatStrings () {
var str = '';
for (var i = 0; i < arguments.length; i++) {
str += arguments[i];
}
return str;
}
Be aware that arguments isn't an array, so it doesn't have methods like join or push. It's just an array-like object (with numerical properties and a length property) so it can be iterated through.
JavaScript has arguments object inside functions. It contains of all params passed to the function.
More info
It is some sort of implicit in the special variable "arguments". Use like this:
function something(arg1, arg2) {
for (var i = 0; i < arguments.length; i++) {
var x = arguments[i];
}
}
Then you can call it like something(1, 2, 3, 'a', 'b', 'c')
More examples here: http://www.jtricks.com/javascript_tutorials/varargs.html
Javascript functions can accept any number of parameters by default. You can see them with the arguments variable.
See here.

Under what circumstances is it necessary to perform an explicit cast of a variable to a string in JavaScript?

Are there any scenarios where it is absolutely necessary to perform an explicit cast of a variable in JavaScript to a String
In the following example it is not necessary:
var n=1;
var s = "Hello" + n;
var s = "Hello"+String(n); //not necessary
I've used a numeric value above, although this need not apply only to numerics.
Yes, if you want "11" instead of 2.
var n = 1;
var s = n + n;
Will be s === 2
Well if your want to display two numbers side by side...
var a=5, b = 10;
alert( a+b ); // yields 15
alert( String(a) + String(b) ); //yields '510'
but i do not know if you would ever want to do something like this..
I would say it is necessary in this situation:
var n = 20;
var m = 10;
var s = String(n) + String(m); // "2010" String
It depends on the type of object you are working with. The basic objects already have a useful toString method that turns them into strings. But custom objects don’t. They will inherit the method from Object.prototype.toString.
So whenever you have a custom object that should return a useful string when converted to string, define a toString method:
function Human(name) {
this.name = name.toString();
this.toString = function() {
return this.name;
};
return this;
}
var alice = new Human("Alice");
alert("Hi, I’m " + alice + ".");
Usually a variable is converted to string when you want to use string methods on that variable. I think that the most useful case is when you must use a string method inside a function and you don't know what type of variable the user passes into the function. For example if you want to calculate the number of characters in a variable:
function length(s)
{
return s.length;
}
With this function you can only work with strings because if the user inserts a number as argument the length property is undefined, because the Number object doesn't have that property, so you must cast the variable:
function length(s)
{
s=s+"";
return s.length;
}
and this time it works.

Categories

Resources