Can I pass a variable number of arguments into a Javascript function? I have little knowledge in JS. I want to implement something like the following:
function CalculateAB3(data, val1, val2, ...)
{
...
}
You can pass multiple parameters in your function and access them via arguments variable. Here is an example of function which returns the sum of all parameters you passed in it
var sum = function () {
var res = 0;
for (var i = 0; i < arguments.length; i++) {
res += parseInt(arguments[i]);
}
return res;
}
You can call it as follows:
sum(1, 2, 3); // returns 6
Simple answer to your question, surely you can
But personally I would like to pass a object rather than n numbers of parameters
Example:
function CalculateAB3(obj)
{
var var1= obj.var1 || 0; //if obj.var1 is null, 0 will be set to var1
//rest of parameters
}
Here || is logical operator for more info visit http://codepb.com/null-coalescing-operator-in-javascript/
A Is there a "null coalescing" operator in JavaScript? is a good read
Yes, you can make it. Use variable arguments like there:
function test() {
for(var i=0; i<arguments.length; i++) {
console.log(arguments[i])
}
}
Related
Hi everyone i need an help.
I try to modify Number.prototype to add the function sum.
I want to add some numbers to my initial number.
Number.prototype.sum = async (...nums) => {
var x = //What I have to write to have my inizial number here?
for (var i = 0;i<nums.length;i++) {
x=x+nums[i]
}
return x
}
console.log((10).sum(2)) // output: 12
console.log((10).sum(4,6)) // output: 20
(I use visual studio code and the hint after this. is only number)
I tried with:
Number.prototype.valueOf(this)
Number.prototype.valueOf(this.number)
Number.parseInt(this.toString())
Number.parseFloat(this.toString())
Number.parseInt(this.number.toString())
Number.parseFloat(this.number.toString())
this.valueOf()
this.number.valueOf()
You have to use function to access the correct this context (which is the number that the method is called on). Arrow functions inherit their this context from the parent scope (the global object in this case). Also async is not needed since you are not doing anything asynchronous here:
Number.prototype.sum = function (...nums) {
var x = this
for (var i = 0; i < nums.length; i++) {
x = x + nums[i]
}
return x
}
console.log((1).sum(2, 3))
Aside from the fact that augmenting native prototypes is a bad idea, wouldn't you think that a function like this is better suited for the Array prototype?
below i have given a javascript code picture `` can any one help me in this code. what do this code. help me in this
function(){
var _ = function()
// The arguments object is an array-like object. It has a length property
// that corresponds to the number of arguments passed into the function
{
var r={},a=arguments;
for(var i=0; i<a.length; i+=2)
r[a[i]]=a[i+1];
return r;
}
}
Here's an example of the script in use with some arguments.
var _ = function() {
var r = {};
var a = arguments;
for(var i=0; i<a.length; i+=2) {
r[a[i]]=a[i+1];
}
console.log(r);
return r;
}
_('a','1','b','2');
The outer function does not make much sense but the inner function named '_' does this essentially _(1,2,3,4) function call will return {1:2,3:4}. Basically, odd arguments are keys and even arguments are values of the returned json object
Function _ converts list of arguments into object
_(name1, value1, name2, value2, ...)
// returns { name1: value1, name2: value2, ... }
I have a forEach function defined to do "something" with all the items in an array:
function forEach(array, action) {
for (var i = 0; i < array.length; i++)
action(array[i]);
}
var numbers = [1, 2, 3, 4, 5], sum = 0;
So I could do:
forEach(numbers, console.log);
And it would print out all the numbers because 'console.log(array[i])' prints the number to the console.
I get that part.
Here's where I'm stuck: If I pass the function below into the place of the action parameter, instead of 'console.log' then at what point does the function know about every element?
forEach(numbers, function(number) {
sum += number;
});
console.log(sum);
// 15
How does it get evaluated? If I pass console.log into the last problem and it still has to be evaluated as 'console.log(array[i])' with the '(array[i])' code next to whatever parameter is being passed in, then doesn't that get applied to the entire function too since that function is the parameter? Such as below:
function(number) { sum += number; }(array[i])
at what point does the function know about every element
At no point (just like when you pass in console.log).
The forEach function calls it on this line:
action(array[i]);
At which point, it only knows about a single value from the array because that is all that is passed into it.
(It also knows about the sum variable because that is defined in a wider scope than the function).
How does it get evaluated?
It creates a new scope (with array, action and i variables) and assigns the function to the action variable - that's a function invocation.
Your
var sum = 0;
forEach([1, 2, 3, 4, 5], function(number) {
sum += number;
});
is just the same as
var sum = 0;
{ // let's assume block scope here
var array = [1, 2, 3, 4, 5],
action = function(number) {
sum += number;
},
i;
for (i = 0; i < array.length; i++)
action(array[i]);
}
If I pass console.log into the last problem and it still has to be evaluated, then doesn't that apply to the entire function too since that function is the parameter?
Yes, exactly. You are passing a function object - and whether get that by referencing the console.log variable or by creating it on the fly (with the function expression) doesn't matter to forEach. It only will get executed with action(…) - where the array[i] value is passed for the number parameter of your function.
In JavaScript, functions are first-class citizens. That means they can be treated as variables, just like strings, numbers, etc.
When you do:
forEach(numbers, function(number) {
sum += number;
});
You are passing forEach an anonymous function. Instead of the function being in a variable, it's created on-the-fly. Inside your forEach function, action will contain your anonymous function.
In for for loop, the action function is called for each element.
Heres the solution to your problems:
function forEach(array, action) {
for (var i = 0; i < array.length; i++){
if(typeof action == 'function'){
action(array[i]);
}else{
var slices = action.match(/(.+)\.([a-zA-Z0-9]+)/);
var object = eval(slices[1]);
var action = slices[2];
object[action](array[i]);
}
}
}
I've tested it with both scenarios and it works like magic
Basically I want to build a function which sorts objects in an array by one of the object's properties/member variables. I am preeeety sure that the comparator function is where the error is hidden, but I am not 100% sure.
The output I should get after the sort function is called is 1,2,3. I get 1,3,2 which means that it is unchanged
This is the entire js code (with some comments):
var arr = [];
//object definition and creation
var main = document.getElementById("main");
var task = {
name: "",
priority: 0
};
//first
var one = Object.create(task);
one.priority = 1;
//secondd
var two = Object.create(task)
two.priority = 3;
//last
var three = Object.create(task);
three.priority = 2;
//append
arr.push(one);
arr.push(two);
arr.push(three);
//sort function
function sortT() {
arr.sort(compareFN);
}
//comperator function
function compareFN() {
return task.priority < task.priority;
}
function print() {
for (var i = 0; i < arr.length; i++) {
console.log(arr[i].priority);
}
}
//execution of the program
print();
sortT();
print();
EDIT: The solution is the following - As stated, the comparator function really was the problem, the correct way to write it is the following:
function compareFN(taskA, taskB) {
return taskA.priority < taskB.priority;
}
There are multiple problems with your comparator:
It refers to the global task object instead of the objects being compared.
It compares the object to itself.
It is supposed to perform a three-way comparison.
Try:
var compareFN = function(a, b) {
return a.priority - b.priority;
}
The compare function needs two arguments: the first and the second element it should compare.
So your compareFN should look like this:
function compareFN(taskA, taskB) {
return taskA.priority - taskB.priority;
}
Edit: As NPE said, it is supposed to perform a three-way comparison, so a simple a < b is not so a great idea here.
You need to change the signature of you compare function to include the two tasks.
For ascending order (normally what you want) you need to do b < a, a < b will do descending order
//comperator function
function compareFN(a, b) {
return b.priority < a.priority;
}
The comparator function returns a negative value, zero or a positive value. Those three comprise what is called here the three-way comparison.
So:
'''
function cmp((a, b) => {
// ascending
return a - b
}
'''
For descending return b - a
In function .concat(), I can pass an arbitrary number of arguments to it.
I understand function overloading in C++, but I don't know how implement a function with unknown number of arguments in JavaScript.
How do I implement an arbitrary number of arguments to a function?
In javascript, you would use the built in parameter called "arguments" which is an array of all the arguments passed to the function. You can obtain it's length with arguments.length and each value from the array arguments[0], arguments[1], etc... Every function has this built in variable that you can use.
For example, a function to concatenate all strings passed to it.
function concatAll() {
var str;
for (var i = 0 ; i < arguments.length; i++) {
str += arguments[i];
}
return(str);
}
var f = concatAll("abc", "def", "ghi"); // "abcdefghi"
You can do this using the arguments object. See the examples and documentation here: https://developer.mozilla.org/en/JavaScript/Reference/Functions_and_function_scope/arguments
Like this -
function f()
{
var i;
for(i=0; i<arguments.length; i++)
{
alert( (i+1) + "th argument: " + arguments[i]);
}
}
All the functions in javascript has a built-in parameter called arguments which is an array containing all the function arguments passed to the function. Just iterate over this array and you will be able to access all the arguments of a function.
As an example, once I've written a function which is used to enable/disable certain button if some specific fields were not empty. I wrote this function this way -
function toggleButton() // I used jquery inside this function
{
var i;
var last = arguments.length-1;
for(i=0; i<last; i++)
{
if( $.trim($(arguments[i]).val()) === "" )
return false;
}
$(arguments[last]).toggle();
return true;
}
and called this function like this -
toggleButton("#idOfFirstField", "#idOfSecondField", "#idOfButtonToToggle");
or like this -
toggleButton("#idOfFirstField", "#idOfSecondField", "#idOfThirdField", "#idOfButtonToToggle");
so in both the cases, I was passing variable number of field ids to the function and it checked that if these fields were empty. If all of them contained some value, then it toggled the visibility of the button.
Like this - use the arguments object all functions have available :
function someFunction() {
for (var i=0,n=arguments.length;i<n;i++) {
// do something with arguments[i];
}
}
You can use the arguments array to access parameters that are not formally declared inside the function:
function printArguments() {
for (i = 0; i < printArguments.arguments.length; i++)
document.writeln(printArguments.arguments[i] + '<br />');
}
printArguments(1, 2, 3, 'etc');
Source: http://www.irt.org/articles/js008/
Any javascript function can have an arbitrary number of arguments. If function execution depends on the number or specific qualities of it's arguments, you'll have to check the arguments object, which can be iterated like an 'Arraylike' object, as others have shown.
In some cases it may be handy to convert the arguments to a real array, using something like
var args = Array.prototoype.slice(arguments).
Here's a blog entry from John Resigs page on method overloading that may interest you.