forEach循环中的JavaScript变量作用域

JavaScript variable scope inside forEach loop

本文关键字:变量 作用域 JavaScript 循环 forEach      更新时间:2023-09-26

在下面的代码中,有一个回调函数与forEach循环一起使用,用于遍历返回的结果。变量"错误"在forEach循环和"错误"在回调相同的变量?

session.getAll(options, function (error, varbinds) {
    varbinds.forEach(function (vb) {
        if (error) 
            console.log('getALL Fail ');
        else              
            console.log(vb.value);            
    });
});

是的,这是同一个变量

我不确定你知道多少。所以,我要详细解释一下。JavaScript中的作用域是在函数级别*。把函数定义看作是树上的点。树上的每个点都是一个作用域。当使用一个变量时,你只能使用当前作用域中的变量,以及顶端的祖先可用的变量(全局作用域)。这里有一些规则。可以帮助你更好地理解的例子:

*UPDATE: ES6 constlet是块级

内部函数可以访问外部函数级变量

function a() {
    var a = 4;
    function b() {
        alert(a); /* a = 4 */
    }
}

形参定义在与

下一行相同的作用域中。
function a(a) {
    // variable "a" is at same scope as the example above
    function b() {
        alert(a);
    }
}

相邻函数中的变量不可访问

函数a()是父函数。B()和c()是它的子函数。这些子变量不能访问彼此的变量。

function a() {
    function b() {
        var aValue = 2;
    }
    function c() {
        alert(aValue); /* "aValue" is undefined here */
    }
}

函数定义的位置是重要的

如果你运行main();,返回5:

function getValue(returnFunc) {
    var a = 7;
    alert(returnFunc());
}
function main() {
    var a = 5;
    getValue(function() { return a; }); // anonymous function becomes "returnFunc"
}

最后,变量覆盖

(function getValue() {
    var a = 5;
    (function () {
        var a = 7;
        alert(a);
    })();
    alert(a);
})();

我试图避免在这些例子中使用自调用函数/生命,但我就是忍不住在最后一个例子中。我认为这是最简单的方法。运行这个,你会得到7,然后5。但是,如果你在内部的"a"中排除"var"…

(function getValue() {
    var a = 5;
    (function () {
        a = 7;
        alert(a);
    })();
    alert(a);
})();

你会得到7,7。这是因为"var"在内存中创建了一个新空间。此外,如果在更高的作用域中存在名称冲突,它将作为不同的变量被覆盖(尽管具有相同的名称)。

关于更多的例子,请参见:JavaScript中变量的作用域是什么?

是的,它是相同的变量,如果您使用var关键字在forEach回调范围内定义另一个error变量,则会发生变化:

session.getAll(options, function (error, varbinds) {
    varbinds.forEach(function (vb) {
        if (error) //Same error as the error parameter above
            console.log('getALL Fail ');
        else              
            console.log(vb.value);            
    });
});
session.getAll(options, function (error, varbinds) {
    varbinds.forEach(function (vb) {
        var error = false; //New error for this closure.
        if (error) 
            console.log('getALL Fail ');
        else              
            console.log(vb.value);            
    });
});