0

私は現在、JavaScript 関数をprivateとして保護する方法を研究しています。呼び出し元が無効な場合、例外がスローされます。次に、ここで問題があります。クロージャーが有効な呼び出し元の内部で定義されている場合、それは内側のクロージャーから有効な呼び出し元を取得する方法ですか?

例えば:

function validCaller() {
    var self = this;
    self.privateFunction1();
    $.each([/*...*/], function (key, val) {
        self.privateFunction2(); 
    });
}

もちろん、privateFunction1呼び出し元validCallerを正しくprivateFunction2取得しますが、匿名関数を呼び出し元として取得するため、アクセスは拒否されます。

式 によってコール スタックから validCaller を取得するのは正しい方法ではありません。caller.caller.callerトレース バックする必要があるレベル数を判断できないためです。また、いくつかの特別なケースでは、無名関数を の外で呼び出す必要がありvalidCallerます。

複雑な方法で質問したのかもしれませんが、簡単な方法は次のとおりです。

関数のスコープ チェーンをキャプチャするにはどうすればよいですか?

4

1 に答える 1

1

何かを非公開にする合理的な方法は、そのことを誰にも言わないことです...

function MyObject(a, b, c)
{
    this.a = a;
    this.b = b;
    this.c = c;

    // Note: NOT using this.private1 = function() { ... }
    function private1()
    {
       ...
    }

    function private2()
    {
       ...
    }

    // Public methods
    this.public1 = function()
    {
       ...
       private1(); // Note; not using "this." in the call
       ...
       private2();
    }
 }

このアプローチでは、メソッド以外の誰もがand ...MyObjectを呼び出すことができないだけでなく、他の人はそれらの名前を見つけることさえできず、偶発的な名前の衝突のリスクはありません。private1private2

プライベート データ メンバーにも同じ方法を使用できます。var x;それらをコンストラクターで単純なローカル変数として宣言するだけで、this.xそれらにアクセスするための構文を使用せずにx. メソッドに関しては、誰もアクセスできず、不注意で上書きされるリスクさえありません。

未承認の関数がメソッドを呼び出すのを防ぐために実行時チェックが本当に必要な場合は、一種の「セキュリティ トークン」を使用できます。

function MyObject()
{
   var authorization = []; // An empty array will do

   this.private_method = function(auth) {
       if (auth !== authorization) throw "Unauthorized call";
       ...
   };

   this.public_method = function() {
       ...
       this.private_method(authorization);
       ...
   };
}

このアプローチを使用すると、どのインスタンスがプライベート メソッドを呼び出しているかを確認できます。

代わりに任意のインスタンスでこの機能が必要な場合は、コンストラクターをクロージャー自体にして、外側のスコープから認証トークンを取得します。

PS: そもそもなぜこれをやりたいのかという文脈はよくわかりませんが、奇妙に聞こえます。

于 2012-07-20T06:03:02.983 に答える