如何在AngularJS中声明控制器?两种写法效率对比问询
在AngularJS里,声明控制器主要有三种常用方式,各有适用场景:
数组注入式(生产环境推荐):就是你给出的代码片段1的写法,把依赖名称放在数组中,最后跟上控制器函数,数组元素和函数参数一一对应:
AppModule.controller('homeController', ['$scope', 'dep1', 'dep2', function($scope, dep1, dep2) { // 控制器逻辑 $scope.aMethod = function() { ... } }]);这种写法不仅能兼容代码压缩,还能让依赖关系一目了然,避免后续维护时混淆参数顺序。
推断式注入(仅适合开发调试):也就是代码片段2的写法,直接传递控制器名称和函数,AngularJS会通过解析函数的参数名来推断依赖:
AppModule.controller('homeController', function($scope, dep1, dep2) { // 控制器逻辑 $scope.aMethod = function() { ... } });写法简单,但代码压缩后参数名会被改成
a、b这类短变量,AngularJS就找不到对应的依赖了,所以不适合生产环境。$inject属性式:把控制器函数单独定义,再通过
$inject属性声明依赖数组,效果和数组注入式一致,适合需要抽离控制器函数复用的场景:function HomeController($scope, dep1, dep2) { // 控制器逻辑 $scope.aMethod = function() { ... } } HomeController.$inject = ['$scope', 'dep1', 'dep2']; AppModule.controller('homeController', HomeController);
咱们直接说结论:第一段代码效率更高,核心依据是它跳过了AngularJS的依赖推断过程。
当使用片段2的推断式注入时,AngularJS需要调用Function.prototype.toString()把控制器函数转换成字符串,再从中提取参数名来匹配对应的服务,这个字符串解析步骤会产生额外的性能开销(虽然绝大多数场景下这个差异微乎其微,几乎感知不到,但从底层逻辑上确实存在)。
而片段1的数组注入式直接明确给出了依赖名称,AngularJS拿到就能直接去查找对应的服务,完全不用做参数解析的额外工作,所以在依赖解析阶段的效率自然更高。
顺便提一句,数组注入式更重要的价值其实是代码压缩后不会失效——片段2的写法一旦压缩,参数名被修改后AngularJS根本找不到对应依赖,这才是生产环境必须用数组注入的核心原因,但回到你问的「效率」问题,解析步骤的差异就是关键依据。
内容的提问来源于stack exchange,提问作者Sergio Reis

