一个函数中的全局变量赋值不能在另一个函数中访问

时间:2018-02-02 19:03:17

标签: javascript scope global-variables

我正在使用地理位置来收集坐标并进行API调用以获取华氏度的天气。我在我的一个函数中为此值指定了全局变量tempNum,该函数使用函数getWeatherByCoordinates(latitude, longitude)将温度添加到页面。

稍后,我试图访问此变量并将值作为参数传递给另一个函数typeConversion,我试图将温度值转换为摄氏温度。它正在返回NaN,在调试时,我无法弄清楚原因。

这是我的HTML和JS。我觉得自从我在全局级别声明我的变量并设置"返回varName"在我为其赋值的函数中,该值应该可以在我的JS中访问;但我可能做错了什么或误解了变量范围。请协助。



var place = document.getElementById("meat");
var header = document.getElementById("header");

var weather = document.getElementById("Weather");

var latitude;
var longitude;
var coordinates = document.getElementById("coordinates");


function success(position) {
     latitude = position.coords.latitude;
     longitude = position.coords.longitude;
        getWeatherByCoordinates(latitude, longitude);
    };
    //else {
    //    //Write Code to alternatively show a Zip-Code Search Box;
    //};


navigator.geolocation.getCurrentPosition(success);
var city = document.getElementById("city");
var weatherDescription = document.getElementById("weather-description");
var roundTempF;
var roundTempC;
var tempNum;
var tempStringFFull

function getWeatherByCoordinates(latitude, longitude) {
    
    var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";

    $.getJSON(fullURL, function (data) {
        
        var tempString = data.main.temp;
        var tempNum = parseInt(tempString);
        roundTempF = Math.floor(tempNum);
        stringF = roundTempF.toString();
        tempStringFFull = stringF + "\xB0" + " F";
        weather.innerText = tempStringFFull;
        city.innerText = data.name;
        weatherDescription.innerText = data.weather[0].description;

        if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("day");
        }
        else {
            $("#whole-page").removeClass("whole");
            $("#whole-page").removeClass("night");
            $("#whole-page").addClass("night");
        };

        event.preventDefault();
    });
    return tempNum;
};



function typeConversion(tempNum) {
    if (changeTempType.innerText === "Celsius") {
        var tempStringC;
        var celsiusDecimal = (tempNum - 32) * (5 / 9);
        roundTempC = Math.floor(celsiusDecimal);
        tempStringC = roundTempC.toString();
        tempStringC += "\xB0" + " C";
        weather.innerText = tempStringC;
        changeTempType.innerText = "Farenheit";
        return;
    }
    else if (changeTempType.innerText === "Farenheit") {
        weather.innerText = tempStringFFull;
        changeTempType.innerText = "Celsius";
        return;
    }
    else {
        weather.innerText = "We are unable to retrieve the weather at this time.  Please try again later";
        changeTempType.innerText = "Celsius";
        return;
    };
};

var changeTempType = document.getElementById("change-temp-type");

changeTempType.addEventListener("click", typeConversion, false);
&#13;
<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
    <link rel="stylesheet" type="text/css" href="css/style.css" />
    <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
    <title>Weather</title>
</head>
<body id="whole-page" class="whole">
    <div class="wrapper"> 

       
    <h2 id="header">Check the Current Temperaturate by Zip Code</h2>
<label>Farenheit</label>
    <input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
        <button id="change-temp-type">Celsius</button>

     <form>    
      <p>Enter the Zip Code to see the Weather there!</p>
      <input id = "Zip-Code" type="text"/>
      
      <input id = "submit-zip" type="button" value="Get Weather!"/>
    </form>
    <div>
            
            <h3 id="city"></h3>
            <h3 id= "Weather" class="temp-text"></h3>
            <h4 id="weather-description"></h4>

      </div>
       
    </div>
<script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script> 
   
<script src="javascript/main.js"></script>
</body>
</html>
&#13;
&#13;
&#13;

1 个答案:

答案 0 :(得分:1)

您有几个问题:

  1. 您在函数中重新声明var tempNum =,这意味着它将是一个只能在函数范围内访问的新变量(保留全局变量)
  2. $.getJSON内部的代码正在使用异步回调 - 这意味着它将比它下面的代码晚一段时间运行。当您return tempNum时,该代码尚未运行。
  3. 你的退货声明并没有真正做任何事情......只需重新分配全局变量即可。
  4. 更新 - 我最初错过的问题:

    1. 您在typeConversion“tempNum”中命名您的函数参数。同样,这将产生一个新变量,只能在该函数的范围内访问。如果您想影响全局,那么此函数根本不需要任何参数,tempNum将按预期引用全局变量。
    2. 我试图澄清下面的所有问题。

      var place = document.getElementById("meat");
      var header = document.getElementById("header");
      
      var weather = document.getElementById("Weather");
      
      var latitude;
      var longitude;
      var coordinates = document.getElementById("coordinates");
      
      
      function success(position) {
           latitude = position.coords.latitude;
           longitude = position.coords.longitude;
              getWeatherByCoordinates(latitude, longitude);
          };
          //else {
          //    //Write Code to alternatively show a Zip-Code Search Box;
          //};
      
      
      navigator.geolocation.getCurrentPosition(success);
      var city = document.getElementById("city");
      var weatherDescription = document.getElementById("weather-description");
      var roundTempF;
      var roundTempC;
      var tempNum;
      var tempStringFFull
      
      function getWeatherByCoordinates(latitude, longitude) {
          
          var fullURL = "http://api.openweathermap.org/data/2.5/weather?lat=" + latitude + "&lon=" + longitude + "&APPID=75ed54453a6e806917cfa439b3fb1dd9&units=imperial";
      
          $.getJSON(fullURL, function (data) {
              
              var tempString = data.main.temp;
              // removed "var tempNum"...
              tempNum = parseInt(tempString);
              roundTempF = Math.floor(tempNum);
              stringF = roundTempF.toString();
              tempStringFFull = stringF + "\xB0" + " F";
              weather.innerText = tempStringFFull;
              city.innerText = data.name;
              weatherDescription.innerText = data.weather[0].description;
      
              if (data.dt > data.sys.sunrise && data.dt < data.sys.sunset) {
                  $("#whole-page").removeClass("whole");
                  $("#whole-page").removeClass("night");
                  $("#whole-page").addClass("day");
              }
              else {
                  $("#whole-page").removeClass("whole");
                  $("#whole-page").removeClass("night");
                  $("#whole-page").addClass("night");
              };
      
              event.preventDefault();
          });
          //return tempNum;
      };
      
      
      // removed the argument "tempNum", just use the global
      function typeConversion() {
          if (changeTempType.innerText === "Celsius") {
              var tempStringC;
              var celsiusDecimal = (tempNum - 32) * (5 / 9);
              roundTempC = Math.floor(celsiusDecimal);
              tempStringC = roundTempC.toString();
              tempStringC += "\xB0" + " C";
              weather.innerText = tempStringC;
              changeTempType.innerText = "Farenheit";
              return;
          }
          else if (changeTempType.innerText === "Farenheit") {
              weather.innerText = tempStringFFull;
              changeTempType.innerText = "Celsius";
              return;
          }
          else {
              weather.innerText = "We are unable to retrieve the weather at this time.  Please try again later";
              changeTempType.innerText = "Celsius";
              return;
          };
      };
      
      var changeTempType = document.getElementById("change-temp-type");
      
      changeTempType.addEventListener("click", typeConversion, false);
      <!DOCTYPE html>
      
      <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
      <head>
          <meta charset="utf-8" />
          <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
          <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet"/>
          <link rel="stylesheet" type="text/css" href="css/style.css" />
          <script defer src="https://use.fontawesome.com/releases/v5.0.6/js/all.js"></script>
          <title>Weather</title>
      </head>
      <body id="whole-page" class="whole">
          <div class="wrapper"> 
      
             
          <h2 id="header">Check the Current Temperaturate by Zip Code</h2>
      <label>Farenheit</label>
          <input type="radio" name="temp-type" value="C" id="Celsius-radio"/><label>Celsius</label>-->
              <button id="change-temp-type">Celsius</button>
      
           <form>    
            <p>Enter the Zip Code to see the Weather there!</p>
            <input id = "Zip-Code" type="text"/>
            
            <input id = "submit-zip" type="button" value="Get Weather!"/>
          </form>
          <div>
                  
                  <h3 id="city"></h3>
                  <h3 id= "Weather" class="temp-text"></h3>
                  <h4 id="weather-description"></h4>
      
            </div>
             
          </div>
      <script src= "https://cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.js"> </script> 
         
      <script src="javascript/main.js"></script>
      </body>
      </html>

      最后一点 - 如果稍后需要访问tempNum的函数运行,这将很好地工作,就像响应用户操作一样。页面加载后几秒内可能仍未定义,因此如果您尝试在页面加载时使用它,它可能仍未定义。在这种情况下,您可能希望将其初始化为某个默认值。

      希望这有帮助。