1

AngularJS stores dependency names as strings, which makes sense, since we can do:

var dependencies = {};
function addDependency(name, value){
   if (typeof name == 'string') {
      dependencies['name'] = value;
   } else {
      //throw err
   }
}

But I don't understand how it's possible to grasp that value through a non-string parameter the way AngularJS does, where it tells you in order to access dependencies, just treat parameters as names:

The simplest way to get hold of the dependencies is to assume that the function parameter names are the names of the dependencies.

someModule.controller('MyController', 
    function($scope, greeter) {
       // ...
    });

In the abover case, I would think greeter would have to be in the form of a string so it could be accessed in a loop like dependencies[argument[i]]; I just don't understand how it's possible in JavaScript to map that parameter's name to a certain dependency name if the argument isn't a string. How is this possible? I'd really like to know how to do this for various syntax improvements in my code.

  • 1
    they're most likely using reflection like code. Example: http://stackoverflow.com/questions/1007981/how-to-get-function-parameter-names-values-dynamically-from-javascript – sirrocco Sep 29 '15 at 14:20
  • ah .. and the second answer for that question is from angular source actually :) – sirrocco Sep 29 '15 at 14:21
  • @sirrocco I saw that wow lol! http://stackoverflow.com/a/12108723/2076675 –  Sep 29 '15 at 14:24
  • So is my question a duplicate of that one, or..? –  Sep 29 '15 at 14:29

1 Answers1

2

It is possible:

var foo = function(foo, bar) {};
foo.toString();
"function (foo, bar) {}"

Now with a little regular expression parsing you can get the names of the parameters. This is what Angular does. It is a bit of a hack, and discouraged. You can use ng-strict-di in your application to throw errors where explicit DI is not declared.

Angular defines plenty of ways to explicitly declare your dependencies.

I suggest using the static $inject property.

MyController.$inject = ['$scope', 'greeter'];
function MyController($scope, greeter) { // . . . }
Martin
  • 15,820
  • 4
  • 47
  • 56
  • Darn, a hack.. Temping, but I'll resist the urge for simpler syntax in the spirit of non hacky code and for the sake of my users CPUs. God forbid someone decides to call dependencies in that hacky way within a loop... –  Sep 29 '15 at 14:32
  • By the way, after injecting dependencies into `MyController` doesn't `function MyController` reset that object into a new function? –  Sep 29 '15 at 14:38
  • This will be cleaned up with Angular2. You will pass Types into Decorators to resolve dependencies. It is my understanding that the implicit hack goes away completely. – Martin Sep 29 '15 at 14:54