38

関数のスコープを別の関数に渡すことはできますか?

例えば、

function a(){
   var x = 5;
   var obj = {..};
   b(<my-scope>);
}

function b(){
   //access x or obj....
}

this.aつまり、 orのようなものを使用せずに、orを直接this.obj使用するだけです。xobj

4

11 に答える 11

34

afunctionのプライベート スコープに真にアクセスする唯一の方法は、 の変数への暗黙的なアクセスを許可するクロージャを形成するようbに宣言することです。aa

ここにいくつかのオプションがあります。

直接アクセス

  1. bの中で宣言しaます。

    function a() {
       var x = 5,
          obj = {};
       function b(){
          // access x or obj...
       }
       b();
    }
    
    a();
    
  2. bの中に入れたくない場合はa、両方をより大きなコンテナ スコープ内に置くことができます。

    function container() {
       var x, obj;
       function a(){
          x = 5;
          obj = {..};
          b();
       }
       function b(){
          // access x or obj...
       }
    }
    
    container.a();
    

これらは、物事を移動するための追加のコードなしaで の変数を直接使用できる唯一の方法です。b少しの「ヘルプ」や間接的な説明で満足している場合は、さらにいくつかのアイデアがあります。

間接アクセス

  1. 変数をパラメーターとして渡すことはできますが、オブジェクトのプロパティ以外への書き込みアクセスはできません。

    function a() {
       var x = 5,
          obj = {};
       b(x, obj);
    }
    
    function b(x, obj){
       // access x or obj...
       // changing x here won't change x in a, but you can modify properties of obj
    }
    
    a();
    

    これのバリエーションとして、更新された値をa次のように渡すことで、書き込みアクセスを取得できます。

    // in a:
    var ret = b(x, obj);
    x = ret.x;
    obj = ret.obj;
    
    // in b:
    return {x : x, obj : obj};
    
  2. のプライベート変数bにアクセスできるゲッターとセッターを使用してオブジェクトを渡すことができます。a

    function a(){
       var x = 5,
          obj = {..},
          translator = {
             getX : function() {return x;},
             setX : function(value) {x = value;},
             getObj : function() {return obj;},
             setObj : function(value) {obj = value;}
          };
       b(translator);
    }
    
    function b(t){
       var x = t.getX(),
          obj = t.getObj();
    
       // use x or obj...
       t.setX(x);
       t.setObj(obj);
    
       // or you can just directly modify obj's properties:
       obj.key = value;
    }
    
    a();
    

    ゲッターとセッターは public で、 のthisオブジェクトに割り当てられますがa、この方法では、 内から明示的に与えられた場合にのみアクセスできますa

  3. そして、変数をオブジェクトに入れて、オブジェクトを渡すことができます:

    function a(){
       var v = {
          x : 5,
          obj : {}
       };
       b(v);
    }
    
    function b(v){
       // access v.x or v.obj...
       // or set new local x and obj variables to these and use them.
    }
    
    a();
    

    バリエーションとして、代わりに呼び出し時にオブジェクトを構築できます。

    function a(){
       var x = 5,
          obj = {};
       b({x : x, obj: obj});
    }
    
    function b(v){
       // access v.x or v.obj...
       // or set new local x and obj variables to these and use them.
    }
    
    a();
    
于 2011-06-14T19:48:01.513 に答える
9

スコープは関数によって作成され、スコープは関数にとどまるため、求めていることに最も近いのは から関数を渡すことa()b()あり、その関数は引き続き からスコープ変数にアクセスできますa()

function a(){
   var x = 5;
   var obj = {..};
   b(function() { /* this can access var x and var obj */ });
}
function b( fn ){

    fn(); // the function passed still has access to the variables from a()

}

b()渡された関数のように変数に直接アクセスすることはできませんが、オブジェクトのように参照が渡されるデータ型には、渡された関数がそのオブジェクトを返す場合にアクセスできます

function a(){
   var x = 5;
   var obj = {..};
   b(function() { x++; return obj; });
}
function b( fn ){

    var obj = fn();
    obj.some_prop = 'some value'; // This new property will be updated in the
                                  //    same obj referenced in a()

}
于 2011-06-14T19:47:18.250 に答える
8

使用はどうですかbind

function funcA(param) {     
    var bscoped = funcB.bind(this);     
    bscoped(param1,param2...)
}
于 2011-06-14T21:37:55.413 に答える
3

あなたは「スコープを通過する」ことはできません...私が知っていることではありません。関数を呼び出すだけでなく、またはを使用して現在のオブジェクト( )を最初のパラメーターとして送信する
ことにより、関数が参照しているオブジェクトを渡すことができます。applycallthis

function b(){
    alert(this.x);
}
function a(){
    this.x = 2;
    b.call(this);
}

関数が特定のスコープにアクセスする唯一の方法は、そのスコープで宣言することです。
ちょっとトリッキー。
それは次のようなものにつながります:

function a(){
    var x = 1;
    function b(){
        alert(x);
    }
}

しかし、それは目的を打ち破るようなものです。

于 2011-06-14T19:31:09.257 に答える
2

他の人が言ったように、そのようなスコープを渡すことはできません。ただし、自己実行匿名関数を使用して変数を適切にスコープすることができます (または、ペダンティックな場合はすぐに実行します)。

(function(){
    var x = 5;
    var obj = {x:x};
    module.a = function(){
        module.b();
    };
    module.b = function(){
        alert(obj.x);    
    };
}());

a();
于 2011-06-14T19:40:39.547 に答える
2

あなたができる最も簡単なことは、あるスコープからそのスコープ外の関数に変数を渡すことだと思います。参照渡し (オブジェクトのように) の場合、bそれに「アクセス」します (以下の obj.someprop を参照)。

function a(){
   var x = 5;
   var obj = {someprop : 1};
   b(x, obj);
   alert(x); => 5
   alert(obj.someprop); //=> 'otherval'
}
function b(aa,obj){
   x += 1; //won't affect x in function a, because x is passed by value
   obj.someprop = 'otherval'; //change obj in function a, is passed by reference
}
于 2011-06-14T19:53:16.987 に答える
-2

次のようなことを試しましたか?

function a(){
   var x = 5;
   var obj = {..};
   b(this);
}
function b(fnA){
   //access x or obj....
   fnA.obj = 6;
}

関数Bをメソッド関数Aとして使用できる場合は、次のようにします。

function a(){
   var x = 5;
   var obj = {..};
   b(this);

   this.b = function (){
      // "this" keyword is still === function a
   }
}
于 2011-06-14T19:44:08.210 に答える
-2
function a(){
   this.x = 5;
   this.obj = {..};
   var self = this;
   b(self);
}
function b(scope){
   //access x or obj....

}
于 2011-06-14T19:25:31.037 に答える