29

javascript オブジェクトのすべてのメソッド (プライベート、特権、またはパブリック) を内部から取得する方法はありますか? サンプル オブジェクトは次のとおりです。

var Test = function() {
// private methods
    function testOne() {}
    function testTwo() {}
    function testThree() {}
// public methods
    function getMethods() {
      for (i in this) {
        alert(i); // shows getMethods, but not private methods
      }
    }
    return { getMethods : getMethods }
}();

// should return ['testOne', 'testTwo', 'testThree', 'getMethods']
Test.getMethods();

現在の問題は のコードですgetMethods()。簡略化された例では、パブリック メソッドのみが返され、プライベート メソッドは返されません。

編集:私のテストコードは、私が望んでいることを過度に複雑にしている可能性があります(またはそうでない可能性があります)。以下が与えられます:

function myFunction() {
  var test1 = 1;
  var test2 = 2;
  var test3 = 3;
} 

myFunction()内からどの変数が存在するかを調べる方法はありますかmyFunction()。擬似コードは次のようになります。

function myFunction() {
  var test1 = 1;
  var test2 = 2;
  var test3 = 3;

  alert(current.properties); // would be nice to get ['test1', 'test2', 'test3']
}
4

7 に答える 7

29

これらのメソッドが隠されている技術的な理由は 2 つあります。

まず、Test オブジェクトでメソッドを実行すると、"this" は、Module Patternごとのパブリック メソッドを含む無名関数の最後に返される型指定されていないオブジェクトになります。

次に、メソッド testOne、testTwo、および testThree は特定のオブジェクトに関連付けられておらず、無名関数のコンテキスト内にのみ存在します。メソッドを内部オブジェクトにアタッチし、パブリック メソッドを介して公開することもできますが、元のパターンほどクリーンではなく、サード パーティからこのコードを取得している場合は役に立ちません。

結果は次のようになります。

var Test = function() {
    var private = {
        testOne : function () {},
        testTwo : function () {},
        testThree : function () {}
    };

    function getMethods() {
        for (i in this) {
            alert(i); // shows getMethods, but not private methods
        }
        for (i in private) {
            alert(i); // private methods
        }
    }
    return { getMethods : getMethods }
}();

// will return ['getMethods', 'testOne', 'testTwo', 'testThree']
Test.getMethods();

編集:

残念だけど違う。ローカル変数のセットには、単一の自動キーワードではアクセスできません。

「var」キーワードを削除すると、それらはグローバル コンテキスト (通常はウィンドウ オブジェクト) にアタッチされますが、それは私が知っている唯一の動作であり、あなたが説明しているものと似ています。ただし、それを行うと、そのオブジェクトには他の多くのプロパティとメソッドが存在することになります。

于 2008-11-09T00:59:51.320 に答える
5

http://netjs.codeplex.com/SourceControl/changeset/view/91169#1773642から

//Reflection

~function (extern) {

var Reflection = this.Reflection = (function () { return Reflection; });

Reflection.prototype = Reflection;

Reflection.constructor = Reflection;

Reflection.getArguments = function (func) {
    var symbols = func.toString(),
        start, end, register;
    start = symbols.indexOf('function');
    if (start !== 0 && start !== 1) return undefined;
    start = symbols.indexOf('(', start);
    end = symbols.indexOf(')', start);
    var args = [];
    symbols.substr(start + 1, end - start - 1).split(',').forEach(function (argument) {
        args.push(argument);
    });
    return args;
};

extern.Reflection = extern.reflection = Reflection;

Function.prototype.getArguments = function () { return Reflection.getArguments(this); }

Function.prototype.getExpectedReturnType = function () { /*ToDo*/ }

} (this);
于 2012-05-10T16:07:05.993 に答える
2

Javascript には、プライベートなものという概念は実際にはありません。そのため、javascript にはリフレクション API 自体がありません。あなたが使用している手法は、それらを非公開にするというよりも、アクセスできないようにするものです。それらは非公開ではなく、非公開です。これらのメソッドを手動でどこかに配置することで、何かを管理できると思います。

于 2008-11-08T23:35:54.123 に答える
1

あなたはvar that = this;トリックを使うことができます:

var Test = function() {
    var that = this;
    function testOne() {}
    function testTwo() {}
    function testThree() {}
    function getMethods() {
      for (i in that) {
        alert(i);
      }
    }
    return { getMethods : getMethods }
}();
于 2008-11-24T21:54:06.733 に答える
1

関数の定義方法を少し変更するだけで、目的を達成できます。関数の実際の実装をオブジェクト リテラルでラップすると、次のようになります。

(function() {
    var obj = {
    // private methods
    testOne: function () {},
    testTwo : function () {},
    testThree: function () {},
    // public methods
    getMethods : function () {
      for (i in this) {
        alert(i); // shows getMethods, but not private methods
      }
    }
    };
    return { getMethods : function(){return obj.getMethods();} }
})();
于 2012-04-16T12:56:59.337 に答える
1

テスト コードの問題の一部は、Test が return ステートメントによって作成されたオブジェクトであること{ getMethods : getMethods }です。代わりに、元の getMethods 関数と同じ名前空間内でのみ使用できます。

于 2008-11-08T23:58:06.123 に答える
0

そんな風に getMethods() を呼んだら静的じゃない?期待どおりに動作させるには、クラスを適切に初期化する必要がありますthisか?

var t = new Test();
t.getMethods();

それでもうまくいかない場合は、JS Serializerを見てください。しばらく前にデバッグに使用しましたが、プライベート変数で機能したと思います。

于 2008-11-08T23:21:57.303 に答える