JavaScript为调用函数变量提供被调用的函数访问

时间:2016-02-23 16:47:48

标签: javascript scope closures

如果我在函数内部定义内部函数,则内部函数可以访问外部函数的变量。如果我希望这个内部函数可以重用并在外部函数之外定义它,那么内部函数现在将失去对外部函数变量的访问。如何使这个新的可重用内部函数可以访问外部函数变量,而不将这些变量作为参数传递?

        function a () {

        var x = [[1,2,3], [1,2,3], [1,2,3]];

        var keys = Object.keys(x[0]);

        for (var i = 0; i < x.length; i++) {
            angular.forEach(keys, loop);
        }

        }

        function loop (key) {
            console.log(key, i);//i is undefined here
        }
        a();

具体来说,是否有一些方法没有1)为此分配变量,2)没有传递变量作为参数,3)没有创建全局变量?

编辑:似乎没有办法做到这一点。但是如果我尝试另一种方法,让可重用函数返回一个新函数,我也无法访问内部范围。为什么会这样,有没有办法使这项工作?

        function a () {

        var x = [[1,2,3], [1,2,3], [1,2,3]];

        var keys = Object.keys(x[0]);
        var myloop = loop();

        for (var i = 0; i < x.length; i++) {
            angular.forEach(keys, myloop);
        }

        }

        function loop (key) {
            return function(key) {
                 console.log(key, i);//i is undefined here
            };
        }
        a();

5 个答案:

答案 0 :(得分:2)

在以下示例中,loop返回一个关闭i值的函数。

function a () {
    var x = [[1,2,3], [1,2,3], [1,2,3]];

    var keys = Object.keys(x[0]);

    for (var i = 0; i < keys.length; i++) {
        keys.forEach(loop(i));
    }
}

function loop (i) {
    return function (key) {
        console.log(key, i);  // i is now defined
    }
}

a();

输出:

0 0
1 0
2 0
0 1
1 1
2 1
0 2
1 2
2 2

答案 1 :(得分:1)

  

如何使这个新的可重用内部函数能够访问外部函数变量,而不将这些变量作为参数传递?

你不能。 JavaScript有lexical scope,而不是动态范围。

另请参阅:What is lexical scope?

答案 2 :(得分:1)

我还想知道另一个我刚刚发现的选项。如果你使用.bind,你可以用i来讨论函数,其他变量将在curried参数之后传入。

 ....
 angular.forEach(keys, loop.bind(null, i));
 ...

 function loop(i, key) {
 ...
 }

答案 3 :(得分:0)

内部函数由外部函数本地处理。因此,您可以从内部函数访问属于外部函数的变量。但是,一旦将内部函数作为外部函数之外的单独函数,就不再能访问外部函数的私有数据变量。

如果这看起来很复杂,这是一个例子:

function A
{
  //variables
  function B
  {
   can use variables of A
  }
}

但是,

    function A
    {
      //variables
    }
    function B
    {
     //cannot access variables of A
    }

答案 4 :(得分:0)

在JS(和许多其他语言)中,有一个可见性上下文。可能的上下文是例如&#34;全球&#34;或功能或阻止。这些上下文是分层的,内部可以读取外部。除非内部将变量声明为全局变量,否则外部永远不会读取内部(封装原则)。