How to identify names of arguments to a function in javascript?

angularjs, dependency-injection, javascript

Solution

If you call `toString` on a function, you get the js declaration of that function:

function a(b,c) {}

a.toString();  // "function a(b,c){}"

then you can parse the string for the order of arguments.

Some investigation into the angular source code confirms this:

if (typeof fn == 'function') {
  if (!($inject = fn.$inject)) {
    $inject = [];
    fnText = fn.toString().replace(STRIP_COMMENTS, '');
    argDecl = fnText.match(FN_ARGS);
    forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
      arg.replace(FN_ARG, function(all, underscore, name){
        $inject.push(name);
      });
    });
    fn.$inject = $inject;
  }
}

They stringify the function, then extract the arguments with a regular expression and store them in an array.

jsFiddle showing how this all works.

Problem

In AngularJS these two controller declarations are equivalent: ``` function BlahCtrl($scope, $http) { ... } function BlahCtrl($http, $scope) { ... } ``` Both `$http` and `$scope` will be the correct variables no matter what order they are in. i.e. the variable named `$http` will always be passed an instance of the `$http` service. How does Angular know which objects to pass in and in what order? I thought this kind of reflection was not possible with javascript.

Original source