Javascript - 从 If/Else 块外部调用变量 Returns 未定义

Javascript - Calling A Variable From Outside Of If/Else Block Returns Undefined

我以为this is how you make a variable inside a if/else block global (Case 3).

connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
    }

    //If Successful - Log Results For Now (Change To Export Results)
    else {
        //console.log(rows);
        foo = rows;

    }

});

console.log(foo); // Out: undefined

为什么我不能访问函数外的变量?

解决方案

好吧,这里的问题之一是了解异步性 的真正含义 。在与@AmmarCSE 和 looking at this great question here on SO 聊天后,我了解到我的问题(显然还有我的代码)结构不正确。

我试图访问一个在函数完成到 运行 之前未定义的变量(对远程数据库的 SQL 查询显然需要比 运行ning 更长的时间才能完成本地脚本)。但是,如果我 异步地 构造我的代码,变量 只会在函数完成后被调用 .

事实证明,这实际上不是变量 scope 的问题,而是变量 defining time 的问题(不确定如果这是定义变量的脚本中时间的正确术语 - CS 专业,请随意编辑正确的术语)。

无论如何,这是新代码:

runSQL(function(result){

//Do Whatever you want with the results - they're defined!!
console.log(result);
)};

function runSQL(callback){

connection.query(sql, function (err,rows){

        //Handle Errors
        if(err){
            //Log The Error & Die
        }

        //If Successful - Log Results For Now (Change To Export Results)
        else {
            callback(rows);            
        }

    });

}

如果你把 var foo = "something" 放在某个地方,它会等于 "something"。我想它没有进入 else 否则它等于 rows... 还有可能 rows 是未定义的吗?

同样,如果执行 foo = 位,在任何地方都没有使用 var foo =,它就变成了一个全局变量,这可能是不可取的...

当您在 error callback 中时,它有自己定义的范围。因此,foo 可见 该闭包和任何嵌套闭包。对于您在 link

中提到的案例 3
var a = 1;

function four() {
  if (true) {
    var a = 4;
  }

  alert(a); // alerts '4', not the global value of '1'
}

它们会在正确的闭包中警告变量,function four(),即使该变量是在 if 块中定义的,它对其父函数也是可见的。

但是,通过不使用前缀 var,您正在 foo 全局 。然而,在回调结果之后记录 undefined 因为此时 foo 尚未定义。如果您在错误回调中登录,它将起作用,但我建议您重组代码以使用回调的 异步 性质

connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
     }

    //If Successful - Log Results For Now (Change To Export Results)
    else{
        //console.log(rows);
        foo = rows;

    }
    console.log(foo);
    });
var result= connection.query(sql, function (err,rows){

    //Handle Errors
    if(err){
        //Log The Error & Die
     }

    //If Successful - Log Results For Now (Change To Export Results)
    else{
        //console.log(rows);
        document.foo = rows;

    }

    });

result.on('result', function(){
    console.log(document.foo);
}