10

AngularJS では、これら 2 つのコントローラー宣言は同等です。

function BlahCtrl($scope, $http) { ... }
function BlahCtrl($http, $scope) { ... }

$httpとの両方$scopeが、順序に関係なく正しい変数になります。つまり、名前$httpが付けられた変数は、常に$httpサービスのインスタンスに渡されます。

Angular は、どのオブジェクトをどの順序で渡すかをどのように認識していますか? このような反映はjavascriptではできないと思いました。

4

2 に答える 2

13

関数を呼び出すtoStringと、その関数のjs宣言を取得します。

function a(b,c) {}

a.toString();  // "function a(b,c){}"

次に、引数の順序について文字列を解析できます。

角度のあるソースコードを調査すると、次のことが確認されます。

if (typeof fn == 'function') {
  if (!($inject = fn.$inject)) {
    $inject = [];
    fnText = fn.toString().replace(STRIP_COMMENTS, '');
    argDecl = fnText.match(FN_ARGS);
    forEach(argDecl[1].split(FN_ARG_SPLIT), function(arg){
      arg.replace(FN_ARG, function(all, underscore, name){
        $inject.push(name);
      });
    });
    fn.$inject = $inject;
  }
}

関数を文字列化し、正規表現を使用して引数を抽出し、配列に格納します。

これがすべてどのように機能するかを示すjsFiddle 。

于 2012-08-20T01:39:31.073 に答える
4

彼らがどのようにそれを行うのかはわかりませんが、簡単な方法があります。

JS のすべてにtoString()メソッドがあります。関数の場合、その特定の関数のソース コードが表示されます (組み込み関数の場合は、 のようなものが得られる場合がありますfunction() { [native code] })。

関数の引数を囲むfirst(とfirst を見つけてみましょう。)次に、空白を取り除き、引数を で分割します,。ほら、引数名の配列を取得します。

function a($scope, $http) { };
function b($http, $scope) { };

function getParameterList(f) {
  var s = f.toString();

  var start = s.indexOf('(');
  var end = s.indexOf(')');

  s = s.substring(start + 1, end);

  return s.replace(/ /g,'').split(',');
}

それでは、テストしてみましょう。

var aParams = getParameterList(a);
var bParams = getParameterList(b); 

alert(aParams[0]); // $scope
alert(aParams[1]); // $http 

alert(bParams[0]); // $http
alert(bParams[1]); // $scope  

フィドル: http://jsfiddle.net/jYPB8/

ただし、 のこの動作はtoString()で定義されてFunction.prototypeおり、再定義される可能性があることに注意してください。その場合、このアルゴリズムは機能しません。

したがって、これはあなたが探していた実際の解決策ではないかもしれませんが、この種のリフレクションがJavaScript で可能であり、実際に行うのは非常に簡単であることをお見せしたかったのです :)

于 2012-08-20T01:16:16.277 に答える