【问题标题】:Understanding AngularJS function $arguments了解 AngularJS 函数 $arguments
【发布时间】:2015-04-02 05:25:11
【问题描述】:

开始接触 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 太习惯了,只有通过一些非常可怕的 hack 才能实现这种功能。

【问题讨论】:

  • 这一切在文档中都有很好的解释,检查这个:docs.angularjs.org/guide/di
  • 第一个显示的表单 JavaScript 中的“可怕的 hack”。 “非 hack”形式分别采用绑定/服务名称,而不是依赖于参数的名称。
  • 这是你要找的东西吗:stackoverflow.com/questions/6921588/…
  • @dfsq 文档只是说它确实有效,而不是它是如何工作的。我的问题更多的是 javascript 如何处理参数而不是 Angular 的依赖注入。
  • 哦,我明白了,这很容易解释。请稍等。

标签: javascript angularjs parameters


【解决方案1】:

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

例如你声明一个函数:

 function abc (first, second) {

 } 

但是当你调用它时,即使没有零参数,你也可以传递任意数量的参数。如果您不传递参数但在声明函数时已定义该参数,您将获得该特定参数的值“未定义”,但不会中断代码执行。

Javascript 在函数内部提供了一个名为“arguments”的特殊本地数组(在 JS 中基本上一切都是对象)。我之所以称之为特殊,是因为它是一个只有一个数组属性“长度”的数组,其他数组方法或属性不可用

abc(firs,second,third) 

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

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

是 Function.length 是另一个属性,您可以通过它检查该函数真正定义了多少参数

【讨论】:

    【解决方案2】:

    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。第三个请求并解析函数的文本表示 - 一个“可怕的 hack”。


    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 中不是可选的。)

    【讨论】:

    • toString 上的正则表达式回答了我的问题。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-10-20
    • 2013-08-16
    • 2011-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多