为什么我的变量在回调函数之外没有定义

Why are my variables undefined outside of the callback function?

本文关键字:定义 函数 我的 变量 回调 为什么      更新时间:2023-09-26

我在函数中设置了一些变量。当在函数内部时,我可以获取、设置并提醒uid1accessToken2,但如果我试图在函数外部提醒它们,它会给出undefined。如何设置值?

这是代码:

FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
        var uid1 = response.authResponse.userID;
        alert(uid1); //works here
        var accessToken2 = response.authResponse.accessToken;
        alert(accessToken2); //works here
    } 
    else if (response.status === 'not_authorized') { } 
    else { }
});
alert(uid1); //does NOT work here
alert(accessToken2); //does NOT work here

您在使用这些变量的范围之外声明了这些变量。要修复代码,请在函数外声明它们:

var uid1 = "";
var accessToken2 = "";
FB.getLoginStatus(function(response) {
    if (response.status === 'connected') {
        uid1 = response.authResponse.userID;
        alert(uid1);
        accessToken2 = response.authResponse.accessToken;
        alert(accessToken2);
    } else if (response.status === 'not_authorized') {
    } else {
    }
    alert(uid1); // Values will be set here.
    alert(accessToken2);
});
alert(uid1); // Values won't reliably be set here.
alert(accessToken2);

更新:正如下面的注释所建议的,因为getLoginStatus方法是异步的,所以在方法外部调用alert()时可能没有值。我在回调中添加了额外的警报,以显示您应该在哪里尝试访问这些值。

您似乎在考虑您的代码,就好像回调函数是在之前执行的一样

alert(uid1); //does NOT work here
alert(accessToken2); 

由于FB.getLoginStatus可能是异步的,所以情况并非如此。它将立即返回并继续显示您的警报。这里的问题不仅仅是可变范围。问题是,在执行回调之前,您无法访问要显示的信息。您无法通过移动变量声明来进行编程。你必须在你的程序/网站/任何东西的设计中考虑到这一事实。

Javascript中的变量具有函数作用域。这意味着它们只存在于用var关键字声明的函数中,除非它们是全局变量。将var关键字从函数中移出,但为了避免它们全局地将其封装在另一个函数中,如下所示:

(function(){
    var uid1, accessToken2;
    FB.getLoginStatus(function(response) {
          if (response.status === 'connected') {
            uid1 = response.authResponse.userID;
          alert(uid1); works here
            accessToken2 = response.authResponse.accessToken;
            alert(accessToken2); //works here
          } else if (response.status === 'not_authorized') {
          } else {
          }
         });
    alert(uid1);  //uid1 declared but not set until callback executes
    alert(accessToken2); //accessToken2 declared but not set until callback executes
    // these alerts will likely NOT display the information
    // they are intended to display because of asynchronous callback 
})();
alert(uid1);  //uid1 is not declared, so this doesn't work
alert(accessToken2); //accessToken2 is not declared, so this doesn't work

因为JavaScript(以及所有编程语言曾经)有作用域?