JavaScript 将作用域传递给另一个函数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6348852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-25 20:22:18  来源:igfitidea点击:

JavaScript pass scope to another function

javascriptnode.jsclosuresscopeserverside-javascript

提问by ciochPep

Is it possible to somehow pass the scope of a function to another?

是否有可能以某种方式将函数的作用域传递给另一个函数?

For example,

例如,

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

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

I would rather access the variables directly, i.e., not using anything like this.aor this.obj, but just use xor objdirectly.

我宁愿直接访问变量,即不使用任何类似this.aor 的东西this.obj,而是直接使用xor obj

采纳答案by ErikE

The only way to truly get access to function a's private scope is to declare binside of aso it forms a closure that allows implicit access to a's variables.

真正访问 functiona的私有范围的唯一方法是在binside 中声明,a因此它形成了一个允许隐式访问a's 变量的闭包。

Here are some options for you.

这里有一些选项供您选择。

Direct Access

直接访问

  1. Declare binside of a.

    function a() {
       var x = 5,
          obj = {};
       function b(){
          // access x or obj...
       }
       b();
    }
    
    a();
    
  2. If you don't want binside of a, then you could have them both inside a larger container scope:

    function container() {
       var x, obj;
       function a(){
          x = 5;
          obj = {..};
          b();
       }
       function b(){
          // access x or obj...
       }
    }
    
    container.a();
    
  1. b里面声明a

    function a() {
       var x = 5,
          obj = {};
       function b(){
          // access x or obj...
       }
       b();
    }
    
    a();
    
  2. 如果你不想b在 of 里面a,那么你可以把它们都放在一个更大的容器范围内:

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

These are the only ways you're going to be able to use a's variables directly in bwithout some extra code to move things around. If you are content with a little bit of "help" and/or indirection, here are a few more ideas.

这些是您能够a直接使用's 变量b而无需一些额外代码来移动事物的唯一方法。如果您对一点“帮助”和/或间接了解感到满意,这里还有一些想法。

Indirect Access

间接访问

  1. You can just pass the variables as parameters, but won't have write access except to properties of objects:

    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();
    

    As a variation on this you could get write access by passing updated values back to alike so:

    // in a:
    var ret = b(x, obj);
    x = ret.x;
    obj = ret.obj;
    
    // in b:
    return {x : x, obj : obj};
    
  2. You could pass ban object with getters and setters that can access a's private variables:

    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();
    

    The getters and setters could be public, assigned to the thisobject of a, but this way they are only accessible if explicitly given out from within a.

  3. And you could put your variables in an object and pass the object around:

    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();
    

    As a variation you can construct the object at call time instead:

    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();
    
  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私有变量的getter 和 setter 的对象:

    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();
    

    getter 和 setter 可以是公共的,分配给 的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();
    

回答by user113716

Scope is created by functions, and a scope stays with a function, so the closest thing to what you're asking will be to pass a function out of a()to b(), and that function will continue to have access to the scoped variables from a().

范围由功能创建和范围与停留的功能,所以最接近你的要求会是怎样传递函数出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()

}

While b()doesn't have direct access to the variables that the function passed does, data types where a reference is passed, like an Object, can be accessed if the function passed returnsthat object.

虽然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()

}

回答by vittore

what about using bind

怎么样使用 bind

function funcA(param) {     
    var bscoped = funcB.bind(this);     
    bscoped(param1,param2...)
}

回答by Raynos

No.

不。

You're accessing the local scope object. The [[Context]].

您正在访问本地范围对象。的[[Context]]

You cannotpublicly access it.

不能公开访问它。

Now since it's node.js you should be able to write a C++ plugin that gives you access to the [[Context]]object. I highlyrecommend against this as it brings proprietary extensions to the JavaScript language.

现在,因为它是 node.js,您应该能够编写一个 C++ 插件来让您访问该[[Context]]对象。我强烈建议不要这样做,因为它为 JavaScript 语言带来了专有扩展。

回答by david

As others have said, you cannot pass scope like that. You can however scope variables properly using self executing anonymous functions (or immediately executing if you're pedantic):

正如其他人所说,您不能像那样传递作用域。但是,您可以使用自执行匿名函数(或者如果您是学究的,则立即执行)正确地限定变量的范围:

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

a();

回答by gion_13

You can't "pass the scope"... not that I know of.
You can pass the object that the function is referring to by using applyor calland send the current object (this) as the first parameter instead of just calling the function:

你不能“通过范围”......我不知道。
您可以使用applyor传递函数引用的对象,call并将当前对象 ( this) 作为第一个参数发送,而不仅仅是调用函数:

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

The only way for a function to access a certain scope is to be declared in that scope.
Kind'a tricky.
That would lead to something like :

函数访问某个范围的唯一方法是在该范围内声明。
有点棘手。
这将导致类似的事情:

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

But that would kind of defeat the purpose.

但这会破坏目的。

回答by KooiInc

I think the simplest thing you cando is passvariables from one scope to a function outside that scope. If you pass by reference (like Objects), b has'access' to it (see obj.someprop in the following):

我认为您可以做的最简单的事情是变量从一个范围传递到该范围之外的函数。如果您通过引用传递(如对象),则 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
}

回答by kgb

Have you tried something like this:

你有没有尝试过这样的事情:

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

If you can stand function B as a method function A then do this:

如果您可以将函数 B 视为方法函数 A,请执行以下操作:

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

   this.b = function (){
      // "this" keyword is still === function a
   }
}

回答by thescientist

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

}

回答by Shawn

function a(){
   var x = 5;
   var obj = {..};
   var b = function()
   {
        document.println(x);
   }
   b.call();
}