Assigning dependencies in controllers using the ES

2020-06-06 02:15发布

问题:

In a video from ng-conf 2015 (Angular 1.3 meets Angular 2.0), the syntax for using ES6 classes as controllers is shown as:

class UnicornHype {
  constructor(unicornHorn, $q) {
    this.$q = $q;
    this.horn = unicornHorn
  }

  findUnicorn {
    return this.$q((resolve, reject) => {
      ...
      this.horn.thrust();
      ...
    });
  }
}

I see that the injected dependencies are assigned as instance properties and I'm wondering if that's a good way to do that. Since the controller's dependencies are usually singleton services, shouldn't they be shared by the instances?

The reason they've done it like this is that methods that were previously on $scope (and therefore in the constructor function's body) are now on the object's shared prototype. John Papa's style guide actually assigns them directly to this (though he's not using ES6 classes - but that shouldn't really matter since they're just syntactic sugar on the constructor function prototype stuff). Is that a good idea?

Another approach would be to keep methods on the prototype but assign the dependencies to local variables (assuming each controller is in its own module file). Something like:

var q, horn;
class UnicornHype {
  constructor(unicornHorn, $q) {
    [q, horn] = [$q, unicornHorn];
  }
  findUnicorn {
    return q(...);
  }
}

Is this better? If yes, would const actually be better than var here? Does this approach have any drawbacks?

A third method (using WeakMaps) is described here: Writing AngularJS Apps Using ES6. Should I forget everything I said above and do it this way?

回答1:

I don't really understand why they use Weakmaps. I quote:

Reason behind choosing WeakMap is, the entries of WeakMap that have objects as keys are removed once the object is garbage collected.

But aren't services long-lived? So why would you need to ensure garbage collection?

In javascript all non-primitives are pointers to the original instance, so the dependencies are always shared. So why would the instance-variable approach not be a good idea?

Anyway, I think the instance-variable approach seems the most future-proof way to go.