0

関数コンストラクターがあります。どの関数 (オブジェクト) が呼び出せるかを制御したい。例を次に示します。

function Bar() {

    // foo can be created only here, when Bar is instantiated
    var foo = new Foo();
}

function Foo() {

   // I'd like to have something like this here:
   if (caller != Bar) {
       alert("Not allowed, the caller is not Bar");
       return;
   }
}

var bar = new Bar();    // this is correct, Foo can be created inside Bar
var foo = new Foo();    // prints "Not allowed, the caller is not Bar" and exits

JSで実装することは可能ですか?そのような種類の制御のためのいくつかの機能はありますか?

このように作成が中止された場合、Foo から何が作成されますか?

4

4 に答える 4

2

特に新しい厳密モードでは、ブラウザー間でコンストラクターの呼び出し元を確実に識別することはできません。

代わりに、同じ自己実行関数の内部で定義するか、または両方を同じ自己実行関数の内部で定義できるためFoo()Bar()Foo()スコープ外ではBar()認識されず、そこでのみ作成できます。

いくつかの例:

// Bar() is only known within a single scope
var Foo;
(function(){
    Foo = function() {
    }

    function Bar() {
    }
})();


// Bar() is only known inside of Foo()'s constructor
function Foo() {
    function Bar() {
    }
}

インスタンス データを完全に非公開にするさまざまな方法について説明している記事 ( http://www.crockford.com/javascript/private.html ) を参考にしてください。ここで求めているものとまったく同じではありませんが、いくつかの同じ手法を使用しています (クロージャに個人データを隠す)。

于 2012-07-16T21:30:36.187 に答える
1

次のようなことを試すことができます:(ただし、これがクロスブラウザソリューションだとは思わないでください)

var caller = Foo.caller.name;
if (caller != "Bar") {
}

詳細については、この回答を参照してください。

別のオプションは、デフォルトで false であるグローバル変数を持ち、許可する関数で true を割り当て、その関数でチェックすることです。

于 2012-07-16T21:34:13.333 に答える
0

Bar 内での Foo オブジェクトの作成を制限したい場合は、in Bar で関数を定義できます。

例えば:

function Bar() {
  var Foo = function Foo() {

    // I'd like to have something like this here:
    if (caller != Bar) {
       alert("Not allowed, the caller is not Bar");
       return;
    }
  }
  var foo = new Foo();
    .
    .
    .
    .
}

これで、Foo は Bar スコープの外では見えなくなりました。

于 2012-07-16T21:31:06.393 に答える
0

あなたは単に公開することができませんでしたFoo:

(function() {



    function Bar() {
        var foo = new Foo();
    }

    function Foo() {

    }

    window.Bar = Bar; //Expose bar to global scope

})();

コンストラクターとして呼び出された関数は、非プリミティブ値を明示的に返さない限り、作成されたオブジェクトを返します。そのreturn;ため、引き続き作成されたオブジェクトが返されます。

于 2012-07-16T21:32:02.250 に答える