最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Understanding AngularJS function $arguments - Stack Overflow

programmeradmin1浏览0评论

Starting to get into angular.js, I've seen a mon pattern relating to arguments of callbacks. An example is the ui-router documentation:

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

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

But, from want I've seen, the myApp.config callback's arguments could be different and it would still behave as expected:

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

How does myApp.config know the difference? Is there done weird magic introspection going on, or is there some basic JS concept that allows for this? E.g. something like:

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

Perhaps I'm too used to python, where this sort of feature would only be possible through some very scary hacks.

Starting to get into angular.js, I've seen a mon pattern relating to arguments of callbacks. An example is the ui-router documentation:

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

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

But, from want I've seen, the myApp.config callback's arguments could be different and it would still behave as expected:

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

How does myApp.config know the difference? Is there done weird magic introspection going on, or is there some basic JS concept that allows for this? E.g. something like:

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

Perhaps I'm too used to python, where this sort of feature would only be possible through some very scary hacks.

Share Improve this question edited Apr 2, 2015 at 6:28 user2864740 62.1k15 gold badges158 silver badges229 bronze badges asked Apr 2, 2015 at 5:25 aquavitaeaquavitae 19.2k12 gold badges66 silver badges109 bronze badges 6
  • 2 It's all well explained in documentation, check this: docs.angularjs/guide/di – dfsq Commented Apr 2, 2015 at 5:28
  • 1 The first form shown is a "scary hack" in JavaScript. The 'non-hack' forms takes in the binding/service names separately instead of relying on the names of the parameters. – user2864740 Commented Apr 2, 2015 at 5:31
  • Is this what you are looking for: stackoverflow./questions/6921588/… – Seamus Commented Apr 2, 2015 at 5:34
  • 1 @dfsq The docs just say that it does work, not how it works. My question is more how javascript deals with arguments than about angular's dependency injection. – aquavitae Commented Apr 2, 2015 at 5:36
  • Oh I see, it's very easy to explain. Just a moment. – dfsq Commented Apr 2, 2015 at 5:37
 |  Show 1 more ment

2 Answers 2

Reset to default 2

This is a "scary hack" used by Angular for one method of dependency injection - where the service names are automatically resolved from the argument names. There is no intrinsic support for such an operation at the language level.

The argument values (but not the argument names) can be accessed via the arguments object within the function. However, the argument names themselves can only be accessed by applying [[ToString]] to the function object and parsing the result1, which is a "scary hack".

In the explicit forms the injected parameters must appear in the same order as the list of supplied dependencies - in this case the names of the parameters don't matter because the service names have been supplied separately.

An excerpt of the forms, from the linked documentation, slightly modified:

// 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) { ..

The first two forms use Function.prototype.apply, which is similar to apply() in Python. The third asks for, and parses, the textual representation of the function - a "scary hack".


1To see how the magical form can be implemented, consider the following:

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

ECMAScript 5 says Function.prototype.toString returns:

An implementation-dependent representation of the function is returned. This representation has the syntax of a FunctionDeclaration. Note in particular that the use and placement of white space, line terminators, and semicolons within the representation String is implementation-dependent.

(I'm not aware of any modern browsers that don't return a 'usable' result; the behavior of returning a representation is not optional is ES5.)

This is basically part of javascript. Javascript is very very flexible regarding functional arguments when it is invoking.

For example you declare a function:

 function abc (first, second) {

 } 

But when you call it, you can pass any number of arguments even without zero argument. If you don't pass an argument but it has been defined when declaring the function, you will get value 'undefined' for that particular argument but it does not interrupt code execution.

Javascript provide a special local array (Basically everything is object in JS) named 'arguments' inside the function. I am calling special because it an Array with only one Array properties 'length' other Array methods or properties are unavailable

abc(firs,second,third) 

Inside abc, we can check provided arguments

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

Yes Function.length is another properties by which you can check how many arguments are really defined by this function

发布评论

评论列表(0)

  1. 暂无评论