Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript将作用域传递给另一个函数_Javascript_Node.js_Closures_Scope_Serverside Javascript - Fatal编程技术网

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

JavaScript将作用域传递给另一个函数,javascript,node.js,closures,scope,serverside-javascript,Javascript,Node.js,Closures,Scope,Serverside Javascript,是否有可能以某种方式将一个函数的范围传递给另一个函数 比如说, function a(){ var x = 5; var obj = {..}; b(<my-scope>); } function b(){ //access x or obj.... } 函数a(){ var x=5; var obj={..}; b(); } 函数b(){ //访问x或obj。。。。 } 我宁愿直接访问变量,也就是说,不使用类似于this.a或this.obj,而是直接

是否有可能以某种方式将一个函数的范围传递给另一个函数

比如说,

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

function b(){
   //access x or obj....
}
函数a(){
var x=5;
var obj={..};
b();
}
函数b(){
//访问x或obj。。。。
}
我宁愿直接访问变量,也就是说,不使用类似于
this.a
this.obj
,而是直接使用
x
obj

您不能“通过范围”。。。据我所知不是这样。
function a(){
   this.x = 5;
   this.obj = {..};
   var self = this;
   b(self);
}
function b(scope){
   //access x or obj....

}
您可以使用
apply
call
传递函数所引用的对象,并将当前对象(
this
)作为第一个参数发送,而不只是调用函数:

function b(){
    alert(this.x);
}
function a(){
    this.x = 2;
    b.call(this);
}
函数访问某个作用域的唯一方法是在该作用域中声明。
有点棘手。
这将导致类似于:

function a(){
    var x = 1;
    function b(){
        alert(x);
    }
}
但那会有点挫败目的。

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

您不能公开访问它


既然是No.js,你应该能够编写一个C++插件,让你访问<代码> [[语境] 对象。我强烈建议您不要这样做,因为它为JavaScript语言带来了专有的扩展。

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


你有没有试过这样的方法:

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
   }
}

作用域是由函数创建的,作用域保留在函数中,因此最接近您要求的是将函数从
a()
传递到
b()
,并且该函数将继续从
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()

}

真正访问函数
a
的私有范围的唯一方法是在
a
内部声明
b
,这样它就形成了一个闭包,允许隐式访问
a
的变量

这里有一些选项供您选择

直接访问

  • a
    中声明
    b

    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()
    
    }
    
    function a() {
       var x = 5,
          obj = {};
       function b(){
          // access x or obj...
       }
       b();
    }
    
    a();
    
  • 如果您不想将
    b
    放在
    a
    的内部,则可以将它们都放在更大的容器范围内:

    function container() {
       var x, obj;
       function a(){
          x = 5;
          obj = {..};
          b();
       }
       function b(){
          // access x or obj...
       }
    }
    
    container.a();
    
  • 这些是您能够直接在
    b
    中使用
    a
    变量的唯一方法,而无需使用一些额外的代码来移动对象。如果你满足于一点“帮助”和/或间接,这里还有一些想法

    间接访问

  • 您可以将变量作为参数传递,但除了对象的属性外,您没有写入权限:

    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};
    
  • 您可以传递带有getter和setter的
    b
    对象,这些getter和setter可以访问
    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();
    
    getter和setter可以是公共的,分配给
    a
    this
    对象,但这样,只有在
    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()
    
    }
    
    function a() {
       var x = 5,
          obj = {};
       function b(){
          // access x or obj...
       }
       b();
    }
    
    a();
    
  • 您可以将变量放入一个对象中,并将该对象传递:

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

  • 我认为最简单的方法就是将变量从一个作用域传递到该作用域之外的函数。如果通过引用传递(如对象),则b可以“访问”它(请参见下文中的obj.someprop):


    使用
    bind

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

    你真的只能用eval来做这件事。下面将给出函数b函数a的范围

      function a(){
         var x = 5;
         var obj = {x};
         eval('('+b.toString()+'())');
      }
      
      function b(){
         //access x or obj....
         console.log(x);
      }
      
      a();  //5
    

    所谓作用域,您指的是方法还是在a()变量中初始化的所有值,等等?顺便说一句,好问题(+1)。此外,如果你发现问题的答案有用,你应该接受这些答案(请看那里有一个勾号),并使用投票。这将帮助你得到更多的答案。这是背景,而不是范围。有没有理由投反对票?如果您可以访问
    [[Context]]
    请一定要让我知道。刚刚给了您一票。如果有人写这个扩展,我很想知道,然后它不是专有的。人们把这称为变化范围,这让我大吃一惊。您所做的只是更改对对象的引用,并将其包含在函数的范围内。要真正改变真正的“范围”,你需要按照你在这里说的做,并改变这些东西指向的框架。@Erik,这是多余的。如果我想把变量作为参数传递,我就不需要作用域。@gion请看我的答案(第三个代码块)。我提出的建议与将它们作为论据传递稍有不同。@Erik我知道。你想要传递一个可以“模拟”作用域的对象。我并不是说它是错误的或者它不起作用。这很好,但这并不是这个问题的答案。@gion我发现给更多的选择而不是只回答所问的问题是有帮助的。例如,“您可以使用动态SQL实现这一点,但您可能不应该这样做,这里还有其他选项”。无论如何,如果你是这么想的话,我没有投你反对票。@Erik:这与node.js无关。有关更多信息,请参阅。当人们不阅读问题并使用浏览器js时,这很烦人。这和只在JavaScript问题中使用jQuery一样糟糕<代码>这个是
    模块
    而不是
    窗口
    ,所以只需写入它即可。我还强烈建议againts重写
    global
    ,因为这是node.js中真正的全局范围(可能有未知的副作用)@Raynos,我读了这个问题,知道它在node中。window关键字在这里是因为我首先在jsfiddle中测试了它,而不是盲目地使用spewi
      function a(){
         var x = 5;
         var obj = {x};
         eval('('+b.toString()+'())');
      }
      
      function b(){
         //access x or obj....
         console.log(x);
      }
      
      a();  //5