Is there any way to get only the unnamed arguments

2019-07-05 02:58发布

In JavaScript functions, arguments is an array-like object containing all arguments to the function, whether they are named or not:

function f(foo, bar) {
    console.log(arguments);
}
f(1, '2', 'foo'); // [1, "2", "foo"]

Is there a way to get only the arguments that are not named, so you could do something like this?

function f(foo, bar) {
    console.log('foo:', foo, 'bar:', bar, 'the rest:', unnamedArguments);
}
f(1, '2', 'foo'); // foo: 1 bar: "2" the rest: ["foo"]

But why?

A real-world use case is for injecting Angular modules as arguments into RequireJS modules:

define([
    'angular',
    'myLibModule', // Exports an Angular module object
    'myOtherLibModule', // Exports an Angular module object
], function(angular, myLibModule, myOtherLibModule) {
    angular.module('MyApp', [myLibModule.name, myOtherLibModule.name]);
});

As the list of module dependencies can get quite large, this quickly becomes very cumbersome. While I could solve it as

define([
    'angular',
    'underscore',
    'myLibModule', // Exports an Angular module object
    'myOtherLibModule', // Exports an Angular module object
], function(angular, _) {
    function angularModuleNames(modules) {
        return _.pluck(_.pick(modules, function(item) {
            return _.has(item, 'name');
        }), 'name');
    }
    angular.module('MyApp', angularModuleNames(arguments));
});

this is also rather cumbersome, and it would be nice if I could do something like this instead:

define([
    'angular',
    'underscore',
    'myLibModule', // Exports an Angular module object
    'myOtherLibModule', // Exports an Angular module object
], function(angular, _) {
    angular.module('MyApp', _.pluck(unnamedArguments, 'name'));
});

Of course, a way to group dependencies in RequireJS would suffice just as well for this particular use case.

1条回答
forever°为你锁心
2楼-- · 2019-07-05 03:09

The number of declared arguments is provided in the length property of the function.

So you can get the arguments whose index is greater or equal to this length :

var undeclaredArgs = [].slice.call(arguments, arguments.callee.length);

As you can't use arguments.callee in strict mode starting from ES5, you should use a reference to the function whenever possible :

var undeclaredArgs = [].slice.call(arguments, f.length);
查看更多
登录 后发表回答