了解AngularJS函数$ arguments

时间:2015-04-02 05:25:11

标签: javascript angularjs parameters

开始进入angular.js,我已经看到了与回调参数有关的常见模式。一个例子是ui-router documentation

var myApp = angular.module('myApp', ['ui.router']);

myApp.config(function($stateProvider, $urlRouterProvider) {
    // Do stuff with ui-router providers
}):

但是,从我已经看过的内容来看,myApp.config回调的参数可能会有所不同,而且它仍会按预期运行:

myApp.config(function(OtherProvider) {
    // Do stuff with provider from another service
});

myApp.config如何知道差异?是否进行了奇怪的魔法内省,或者是否有一些基本的JS概念允许这样做?例如。类似的东西:

myApp.config = function(callback) {
    var providerNames = callback.argumentNames;
    var providers = this.findProviders(providerNames);
};

也许我已经习惯了python,只有通过一些非常可怕的黑客才能实现这种功能。

2 个答案:

答案 0 :(得分:2)

这基本上是javascript的一部分。 Javascript在调用时对函数参数非常灵活。

例如,您声明了一个函数:

 function abc (first, second) {

 } 

但是当你调用它时,即使没有零参数,你也可以传递任意数量的参数。如果您没有通过参数但是在声明函数时已经定义了参数,那么您将获得价值' undefined'对于该特定参数,但它不会中断代码执行。

Javascript提供了一个特殊的局部数组(基本上所有东西都是JS中的对象)名为' arguments'在功能里面。我称之为特殊,因为它只是一个只有一个数组属性的数组'长度'其他数组方法或属性不可用

abc(firs,second,third) 

在abc中,我们可以检查提供的参数

function abc (first, second) {
  var args_total = arguments.length; 
  var no_of_defined_args = Function.length;
} 

是Function.length是另一个属性,您可以通过该属性检查此函数实际定义的参数数量

答案 1 :(得分:1)

这个 是一个可怕的黑客"由Angular for one method of dependency injection使用 - 其中服务名称从参数名称自动解析。 在语言层面上没有这种操作的内在支持。

可以通过函数中的arguments对象访问参数值(但参数名称)。但是,参数名称本身只能通过将[[ToString]]应用于函数对象并解析结果 1 来访问 ,其中一个可怕的黑客"。

在显式表单中,注入的参数必须以与提供的依赖项列表相同的顺序出现 - 在这种情况下,参数的名称并不重要,因为服务名称是单独提供的。

链接文档中的表单摘录略有修改:

// service names supplied separately
//  - only Order of parameters matters
someModule.controller('MyController',
  ['$scope', 'greeter', function(I_am_a_scope, greeter) { ..

// service names supplied separately
//  - only Order of parameters matters
var MyController = function($scope, GREETER) { ..
MyController.$inject = ['$scope', 'greeter'];

// "scary hack" magic of Angular JS, as service names not specified separately
//  - the Name of the parameters is used as service name
// arguably Too Much Magic (TM), and a source of pain for minification
someModule.controller('MyController', function(greeter, $scope) { ..

前两个表单使用Function.prototype.apply,类似于apply() in Python。第三个要求并解析函数的文本表示 - 一个"可怕的黑客"。


1 要了解如何实施神奇形式,请考虑以下事项:

f = function (a,b) { return a+b }
f.toString() // e.g. -> "function (a, b) { return a + b; }"

ECMAScript 5说Function.prototype.toString返回:

  

返回函数的依赖于实现的表示。此表示具有FunctionDeclaration的语法。请特别注意,表示字符串中的空格,行终止符和分号的使用和放置取决于实现。

(我不知道任何现代浏览器都没有返回可用的'结果;返回 a 表示的行为不是可选的ES5。)