函数是一等公民
In JavaScript and other modern languages (Scala, Haskell, LISP, etc.), functions are treated as first-class citizens. Specifically, this means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures. Some programming language theorists require support for anonymous functions (function literals) as well. In languages with first-class functions, the names of functions do not have any special status; they are treated like ordinary variables with a function type.1 https://en.wikipedia.org/wiki/First-class_function
上面的例子可以重构为:
var myController = function ($scope, ... ) {
console.log($scope);
$scope.message = "Hello world"
};
my_app.controller('my_controller' , myController );
在这种情况下.controller
方法存储myController
AngularJS 缓存中的对象$controllerProvider
服务。 IE。cache["my_controller"] = myController;
后来当$compile
服务遇到需要控制器的指令:
<div ng-controller="my_controller">
{{message}}
</div>
The $compile
服务创建一个新范围,检索myController
函数从$controller
服务缓存,并使用新作用域作为函数的第一个参数来调用该函数。
The $compile
服务还创造了$watch
监听功能,跟踪$scope.message
多变的。在每个消化周期,如果$scope.message
发生变化时,DOM 会相应更新。
在问题的示例中:
//These are function invocations, the variable must be defined
console.log( boo ) ; // ERROR: boo is not defined
my_instance.some_method( boo ) ; // ERROR: boo is not defined
最后一种形式使用匿名函数文字(或函数表达式)。匿名函数是作为参数传递给名为的方法的对象.some_method
.
//The anonymous function is an object passed as an argument
//boo is a parameter to be supplied when the function is invoked
my_instance.some_method( function( boo ) { } ) ; // NO ERROR
有关函数文字的更多信息,请参阅MDN JavaScript 参考 -- 函数表达式 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/function*.
依赖注入和按名称连接参数
通常在 JavaScript 中,函数参数是相连的按位置。在AngularJS框架中,函数参数被注入by name。这是怎么做到的?
来自文档:
推理
在 JavaScript 中调用toString()
on 函数返回函数定义。然后可以解析定义并提取函数参数。
-- AngularJS $injector 服务 API 参考 -- 推理 https://docs.angularjs.org/api/auto/service/%24injector#inference
所以在例子中:
my_app.controller('my_controller' , function( $scope , ... ) { ... }
The $injector
服务做了一个toString()
控制器构造函数并对其进行解析。该服务检测到$scope
是函数的第一个参数,并使用该知识来正确调用该函数。
你可以看到fn.toString()
正在使用在源代码中 https://github.com/angular/angular.js/blob/master/src/auto/injector.js#L72.