回调函数是否在javascript中创建新范围

时间:2016-11-15 04:59:50

标签: javascript

function hello() {
  var result = [];
  var str = 'I am here';
   function inner() {
    var result = [];
     for (var i=0;i<10;i++) {
        result.push(i);
     }
     return result;
   }
}

在上面的代码中我调用函数hello()时,返回值为空[],也没有console.log来自内部函数的str。但是,在下面的代码集中,我使用了一个回调函数:

 function forEach(cb) {
   for(var i =0;i<10;i++) {
    cb(i);
   }
}

function hello() {
   var result = [];
   var str = 'I am here';
   forEach(function(num) {
    console.log(str);
     result.push(num);
   }); 
   return result;
}

问题是为什么两个函数都反应了,并给出了不同的输出?注意;在两个代码中都有一个内部函数,它应该创建一个可以访问外部作用域的新作用域?有没有人对这个问题有一个很好的解释? 谢谢

2 个答案:

答案 0 :(得分:2)

在第一个代码块中,inner是在hello内声明的新函数。它不会执行,因为你没有调用它。它在调用时会在hello内创建一个新的子范围。但是,由于hello()实际上没有返回任何内容且未调用inner(),因此当您致电undefined时,您会收到hello()。您可以通过更改为此来修复此问题(您可以运行此代码段以查看返回值):

function hello() {
    var str = 'I am here';

    // declare inner
    function inner() {
        var result = [];
        for (var i = 0; i < 10; i++) {
            result.push(i);
        }
        return result;
    }

    // now call inner() and return its result
    return inner();
}

console.log(hello());

在其他函数中声明的函数会创建一个新范围。 Javascript中的每个函数声明和相应的调用都会创建一个新的范围。如果函数在另一个函数中,那么该内部函数内的代码可以访问其本地作用域和父作用域,这可以嵌套到嵌套函数声明的深度。

  

问题是为什么两个职能部门都做出了反应,并给出了不同的看法   输出?注意;两个代码都有一个内在的功能   创建一个可以访问外部范围的新范围?有没有人   对这个问题有一个很好的解释?感谢

在第一个例子中,你从未调用内部函数,所以它从未执行过。

在第二个示例中,将内联匿名函数引用作为函数参数传递给forEach()函数。当forEach()函数执行时,它会使用代码行cb(i)调用您的回调函数,这样就可以在第二个示例中调用回调函数。 forEach()为您调用它。

此外,在第二个示例中,本地声明的回调函数正在访问父作用域并修改result数组(这是完全允许的)。在您的第一个代码示例中,您在result函数范围中声明了一个新的inner变量,然后返回该变量。您没有访问父result变量。当声明一个与父作用域中的变量同名的局部变量时,局部变量会覆盖父变量(基本上隐藏父变量),并且本地作用域中对该变量的任何引用只能访问局部变量。

您可以编写第一个代码示例来使用父作用域result变量,如下所示:

function hello() {
    var result = [];
    var str = 'I am here';

    // declare inner
    function inner() {
        for (var i = 0; i < 10; i++) {
            result.push(i);
        }
        return result;
    }

    // now call inner() and return result
    inner();
    return result;
}

console.log(hello());

答案 1 :(得分:1)

你混淆了函数声明和调用。

声明一个功能可以通过多种方式完成:

function myNewFunction() {}

现在这个函数存在于当前作用域中,但除非被调用,否则不会执行。

你可以像这样调用这个函数。现在你的功能将被执行。

myNewFunction();

可以将函数及其范围与变量进行比较。在另一个函数内定义的函数只能在父函数内部访问。我举个例子。

    function myMegaFunction() {
        console.log("in mega");
        function mySmallFunction() {
            console.log("in small");
        }
    }

    myMegaFunction(); 

这只会打印 - '在mega'。如果您在mySmallFunction()内拨打myMegaFunction,则会打印两行。

现在让我们采取更复杂的方案:

    function myMegaFunction() {
        console.log("in mega");
        var str = "car";
        var result = function mySmallFunction() {
            console.log("in a small", str);
        }
        return result;
    }
        
    var resultingFunction = myMegaFunction();
    resultingFunction();

这将首先打印以下内容: in mega in a small car

基本上,这是像变量一样传递的函数。它们也可以在以后执行。