scm
scm

Reputation: 61

How can you use arguments.length to find the number of arguments passed to a function?

I am writing a function that needs to determine how many arguments have been passed to itself. I am able to get this information after a function has been declared, but whenever I call it from within a function using arguments.length, I get the same inaccurate answer.

Example using {function}.length after function is declared:
const noParameters = () => {};
const oneParameter = (a) => {};
const twoParameters = (a, b) => {};

console.log(noParameters.length);   // 0
console.log(oneParameter.length);   // 1
console.log(twoParameters.length);  // 2
Example using argument.length within the function
const noArguments = () => {
  return arguments.length
}

const oneArgument = () => {
  return arguments.length
}

const twoArguments = () => {
  return arguments.length
}

console.log(noArguments());       // 5
console.log(oneArgument(1));      // 5
console.log(twoArguments(1, 2));  // 5

I am trying to understand the arguments object itself, but it doesn't seem to be related to the function it is returning. From printing arguments to the console, it appears to be related to the file I am running:

const whatIsArgument = () => {
  return arguments
}

console.log(whatIsArgument());

// Console returns: 
[Arguments] {
  '0': {},
  '1': 
   { [Function: require]
     resolve: { [Function: resolve] paths: [Function: paths] },
     main: 
      Module {
        id: '.',
        exports: {},
        parent: null,
        filename: '{redacted filepath}/test.js',
        loaded: false,
        children: [],
        paths: [Array] },
     extensions: { '.js': [Function], '.json': [Function], '.node': [Function] },
     cache: 
      { '{redacted filepath}/test.js': [Module] } },
  '2': 
   Module {
     id: '.',
     exports: {},
     parent: null,
     filename: '/{redacted filepath}/test.js',
     loaded: false,
     children: [],
     paths: 
      [ {array of all the files in my project directory } ] },
  '3': '{redacted filepath}/test.js',
  '4': '{redacted filepath}' }

Note: file-paths have been redacted for privacy.

Does anyone have an idea of what's going on here? Everything online indicated that arguments.length should return what I'm looking for, so I'm at a loss.

Upvotes: 0

Views: 3238

Answers (4)

Jaseem Khan
Jaseem Khan

Reputation: 1

I faced this problem a few days ago when I was working on a LeetCode problem.

2703. Return Length of Arguments Passed

The problem was about counting the length of arguments passed to a function. After solving it, this code leetcode accept my code problem solved successfully. I am very happy.

let argumentsLengths = function () {
    return arguments.length;
}
argumentsLengths(1, 2, 3); // 3

I realized that the same task could be accomplished with another function. This function is also performing the task properly and is working correctly.

let argumentsLength = function(...args) {
    return arguments.length;
};
argumentsLength(1, 2, 3); // 3

So, I considered which function would be better to use in the future. I researched and understood it well. The arguments object is the old-fashioned way to handle variable arguments. ES6 introduced the rest parameter ...args, which collects the arguments into an array named args. This is useful if you need to treat the arguments as a true array (e.g., using array methods like map, filter, reduce, etc.). I recently wrote a comprehensive article on this topic, where I explained ...args and arguments in detail, covering every point I learned. I hope you find it informative and enjoyable. If you have any further insights or questions, please feel free to share them with me. Rest Parameters (‘…args’) vs ‘arguments’

Upvotes: -1

Klaycon
Klaycon

Reputation: 11080

The arguments object is the old-fashioned way to handle variable arguments. From the MDN page on arguments:

If you're writing ES6 compatible code, then rest parameters should be preferred.

You're observing this strange behavior due to a quirk of ES6 arrow functions, detailed in the MDN page (emphasis mine):

An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords.

Since you're using arrow functions, you should handle variable arguments with rest parameters.

const noArguments = (...args) => {
  return args.length
}

const oneArgument = (...args) => {
  return args.length
}

const twoArguments = (...args) => {
  return args.length
}

console.log(noArguments());       // 0
console.log(oneArgument(1));      // 1
console.log(twoArguments(1, 2));  // 2

Upvotes: 4

Georgi B. Nikolov
Georgi B. Nikolov

Reputation: 998

While this does not answer your question directly, arguments is not really used in modern Javascript besides when compiling and adapting es6 code to es5.

You should know that this keyword behaviour and its contents range from implementation to implementation.

You will be way better just using a rest parameter like this:

const myFunc = (...args) => args.forEach(console.log)

Please also note that accessing it with myFunc.arguments is deprecated and its support is not guaranteed.

Upvotes: 0

Talg123
Talg123

Reputation: 1506

That not how you pass arguments. that how arguments works:

const myFunc = (...args) => {
  return args.length
};

console.log(myFunc(1,2,3,4))
console.log(myFunc())

Upvotes: 2

Related Questions