In PHP there is func_num_args and func_get_args, is there something similar for JavaScript?
For modern Javascript or Typescript:
class Foo {
reallyCoolMethodISwear(...args) { return args.length; }
}
function reallyCoolFunction(i, ...args) { return args[i]; }
const allHailTheLambda = (...args) => {
return args.constructor == Array;
};
const x = new Foo().reallyCoolMethodISwear(0, 1, 2, 3, 4);
const y = reallyCoolFunction(3, 0, 1, 2, 3, 4, 5, 6);
const z = allHailTheLambda(43110, "world");
console.log(x, y, z); // 5 3 true
For ancient Javascript:
Use arguments. You can access it like an array. Use arguments.length for the number of arguments.
The arguments is an array-like object (not an actual array). Example function...
function testArguments () // <-- notice no arguments specified
{
console.log(arguments); // outputs the arguments to the console
var htmlOutput = "";
for (var i=0; i < arguments.length; i++) {
htmlOutput += '<li>' + arguments[i] + '</li>';
}
document.write('<ul>' + htmlOutput + '</ul>');
}
Try it out...
testArguments("This", "is", "a", "test"); // outputs ["This","is","a","test"]
testArguments(1,2,3,4,5,6,7,8,9); // outputs [1,2,3,4,5,6,7,8,9]
The full details: https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments
ES6 allows a construct where a function argument is specified with a "..." notation such as
function testArgs (...args) {
// Where you can test picking the first element
console.log(args[0]);
}
The arguments object is where the functions arguments are stored.
The arguments object acts and looks like an array, it basically is, it just doesn't have the methods that arrays do, for example:
Array.forEach(callback[, thisArg]);
Array.map(callback[, thisArg])
Array.filter(callback[, thisArg]);
Array.slice(begin[, end])
Array.indexOf(searchElement[, fromIndex])
I think the best way to convert a arguments object to a real Array is like so:
argumentsArray = [].slice.apply(arguments);
That will make it an array;
reusable:
function ArgumentsToArray(args) {
return [].slice.apply(args);
}
(function() {
args = ArgumentsToArray(arguments);
args.forEach(function(value) {
console.log('value ===', value);
});
})('name', 1, {}, 'two', 3)
result:
> value === name
> value === 1
> value === Object {}
> value === two
> value === 3
You can also convert it to an array if you prefer. If Array generics are available:
var args = Array.slice(arguments)
Otherwise:
var args = Array.prototype.slice.call(arguments);
from Mozilla MDN:
You should not slice on arguments because it prevents optimizations in
JavaScript engines (V8 for example).
As many other pointed out, arguments contains all the arguments passed to a function.
If you want to call another function with the same args, use apply
Example:
var is_debug = true;
var debug = function() {
if (is_debug) {
console.log.apply(console, arguments);
}
}
debug("message", "another argument")
Similar answer to Gunnar, with more complete example:
You can even transparently return the whole thing:
function dumpArguments(...args) {
for (var i = 0; i < args.length; i++)
console.log(args[i]);
return args;
}
dumpArguments("foo", "bar", true, 42, ["yes", "no"], { 'banana': true });
Output:
foo
bar
true
42
["yes","no"]
{"banana":true}
https://codepen.io/fnocke/pen/mmoxOr?editors=0010
Yes if you have no idea that how many arguments are possible at the time of function declaration then you can declare the function with no parameters and can access all variables by arguments array which are passed at the time of function calling.
In ES6 you can do something like this:
function foo(...args)
{
let [a,b,...c] = args;
console.log(a,b,c);
}
foo(1, null,"x",true, undefined);
Hope this helps:
function x(...args) {
console.log( {...[...args] } );
}
x({a:1,b:2}, 'test');
Output:
{ '0': { a: 1, b: 2 }, '1': 'test' }
Hope this could be the helpful code:
function lazyLoadIcons(){
for(let i = 0; i < arguments.length; i++) {
var elements = document.querySelectorAll(arguments[i]);
elements.forEach(function(item){
item.classList.add('loaded');
});
}
}
lazyLoadIcons('.simple-2col', '.ftr-blue-ad', '.btm-numb');
~ Rahul Daksh
In ES6, use Array.from:
function foo()
{
foo.bar = Array.from(arguments);
foo.baz = foo.bar.join();
}
foo(1,2,3,4,5,6,7);
foo.bar // Array [1, 2, 3, 4, 5, 6, 7]
foo.baz // "1,2,3,4,5,6,7"
For non-ES6 code, use JSON.stringify and JSON.parse:
function foo()
{
foo.bar = JSON.stringify(arguments);
foo.baz = JSON.parse(foo.bar);
}
/* Atomic Data */
foo(1,2,3,4,5,6,7);
foo.bar // "{"0":1,"1":2,"2":3,"3":4,"4":5,"5":6,"6":7}"
foo.baz // [object Object]
/* Structured Data */
foo({1:2},[3,4],/5,6/,Date())
foo.bar //"{"0":{"1":2},"1":[3,4],"2":{},"3":"Tue Dec 17 2013 16:25:44 GMT-0800 (Pacific Standard Time)"}"
foo.baz // [object Object]
If preservation is needed instead of stringification, use the internal structured cloning algorithm.
If DOM nodes are passed, use XMLSerializer as in an unrelated question.
with (new XMLSerializer()) {serializeToString(document.documentElement) }
If running as a bookmarklet, you may need to wrap the each structured data argument in an Error constructor for JSON.stringify to work properly.
References
Structure Clone CommonJS Module
JS Object Clone
MDN: Array.from()
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
I was able to complete the task using .filter() and a For Loop, but not sure why I cannot use the format in my second example. First example works fine.
function destroyer(arr) {
for(i=1; i < arguments.length; i++){
number = arguments[i];
arr = arr.filter(function(num){
return num !== number;
});
}
return arr;
}
destroyer([1, 2, 3, 1, 2, 3], 2, 3);
Tried to replace the return num !== number; with return num!==arguments[i] but the arguments[i] does not appear to return the numeric value.
Because arguments refers to a different functions arguments at that point.
Every time you enter a function, arguments will refer to the currently executing functions arguments. It wouldn't make much sense for arguments to only refer to the top-level functions arguments.
Example:
function a() {
console.log(arguments[0]);
var b = function() {
console.log(arguments[0]);
};
b('This is b');
}
a('This is a');
Here is the test code:
function fn(i, j) {
arguments = [3, 4];
console.log(i, j); // 1, 2
console.log(arguments); // [3, 4]
}
fn(1, 2);
in the function , I reset the arguments object
However, the arguments object is changed, but the formal parameter which passed in is not chaned, I think they are the same, so what's the differences?
arguments is an array-like object, which has reference to all the parameters passed to it. Here, you have merely reassigned arguments to point to some other object. If you want to change the actual parameters, you have to change the elements of arguments, like this
function fn(i, j) {
arguments[0] = -1;
console.log(i, j); // -1, 2
console.log(arguments); // { '0': -1, '1': 2 }
}
fn(1, 2)
Quoting from arguments, MDN docs
The arguments object is not an Array. It is similar to an Array, but
does not have any Array properties except length. For example, it does
not have the pop method.
However it can be converted to a real Array:
var args = Array.prototype.slice.call(arguments);
If Array generics
are available, one can use the following instead:
var args = Array.slice(arguments);
You are replacing the arguments array (actually an array-like object) with a new array. They are separate objects and exist side by side. Replacing the reference of the arguments variable doesn't make the function use the new array as arguments, it still has an internal reference to the original object.
If you change the contents of the arguments object, it will reflect on the function arguments:
function fn(i, j) {
arguments[0] = 3;
arguments[1] = 4;
console.log(i, j); // 3, 4
console.log(arguments); // [3, 4]
}
fn(1, 2);
I would like to write a javascript function that works something like this...
f([["a"]], function(e){alert(e);});
// results in alert("a");
f([["a"], ["b"]], function(e1,e2){alert(e1 + ":" + e2);});
//results in alert("a:b");
f([["a", "b"], ["c"]], function(e1,e2){alert(e1 + ":" + e2);});
//results in alert("a:c");alert("b:c");
I can think of a recursive solution for the looping, but how do I send a "unknown" number of variables to a function?
If you put all your arguments into an array (lets call it foo), you can call a function fn with those arguments by using the apply-function.
fn.apply(null, foo)
The first argument (null in this case) is whatever you want this to be inside of the called function. null will probably work for you.
According to this page, you can access any/all arguments using the arguments variable:
function f() {
for( var i = 0; i < arguments.length; i++ ) {
//do something with arguments[i]
}
}
[EDIT]
Now that I understand what you're trying to do, here's a (dirty) way to do it:
Seriously, don't do it this way. It's horrible. Puppies will die.
function f(arr, fn) {
var s = "fn(";
for( var i = 0; i < arr.length; i++ ) {
//you can implement your recursive code here if you like; I'm just doing the base cases
s += arr[i];
if(i+1 < arr.length) {
s += ",";
}
}
s += ");";
eval(s);
}
And for a cleaner way:
function f(arr, fn) {
fn.apply(this, arr);
}
Within the function you can use the variable arguments to see what was passed. IE
function blah() {
console.log(arguments);
}
blah(1, 2); // [1, 2]
blah([1, 2], [3]); // [[1,2], [3]]
blah(1, [2, 3], "string"); // [1, [2, 3], "string"]
You can use the arguments variable that each function has to go through all the passed in arguments.
function myConcat(separator) {
var result = ""; // initialize list
// iterate through arguments
for (var i = 1; i < arguments.length; i++) {
result += arguments[i] + separator;
}
return result;
}
See this article for a discussion of variable number of arguments.
You can use the arguments pseudo-array available within the function to get the arguments passed in without declaring them explicitly (i,e. regardless of whether you define an argument for a function, you can access everything passed in to the function via the arguments implicit variable within that function).