Javascript 每次调用方法时,变量都未定义

Javascript 每次调用方法时,变量都未定义,javascript,Javascript,我正在构建一个ES5天气应用程序,以便更好地理解JavaScript。我遇到了一个问题,我想出了一个解决办法&让它工作起来,但我仍然不明白为什么我最初的解决方案会给我带来问题。我试图在更深的层次上理解JavaScript。泰 让我困惑的是: class UI { constructor() { } showWeatherResults(weather) { let renderedSection; let p1; if (p1) {

我正在构建一个ES5天气应用程序,以便更好地理解JavaScript。我遇到了一个问题,我想出了一个解决办法&让它工作起来,但我仍然不明白为什么我最初的解决方案会给我带来问题。我试图在更深的层次上理解JavaScript。泰

让我困惑的是:

class UI {
  constructor() {  
    
  }
  showWeatherResults(weather) {
    let renderedSection;
    let p1;
    if (p1) {
      p1.innerHTML = `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
    } else {
      renderedSection = document.querySelector('#renderedContent');
      p1 = document.createElement("p");
      renderedSection.appendChild(p1);
      p1.innerHTML += `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
      this.clearInput();
    }
  }
  clearInput() {
    let input = document.querySelector('input');
    input.value = '';
  }
}
<h1>Enter your zipcode here</h1>
<form>
  <input id="zipInput" type="text">
  <button id="zipButton">Submit</button>
</form>
<section id="renderedContent"></section>
const weatherApp = new WeatherApp;
const ui = new UI;
const zipButton = document.querySelector('#zipButton');

// Event listeners
zipButton.addEventListener('click', async (e) => {
  e.preventDefault();
  const weatherResult = await weatherApp.getWeather()
  ui.showWeatherResults(weatherResult);
});
  • 在我点击submit并进行API调用之后,所有内容都显示在我的屏幕上,我的第二个API调用创建了一个额外的段落HTML标记,而不是替换最初的一个。这是因为以下if语句永远不会为真:
  • 但我认为第二次是正确的,因为我已经在前面的函数中创建了它。但它总是未定义的。为什么会发生这种情况

  • 另外,我想创建一个单独的方法,名为

    生成内容(p1)

  • 这将运行:

    p1.innerHTML += `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
    
    但是p1始终是未定义的

    总结: 我的解决方案是添加类/Id并搜索它们。如果它们是真的,那么这是第二个API调用。这很有效。然而,我现在觉得我遗漏了一些东西(在我对JavaScript的理解中)

    我的代码:

    class UI {
      constructor() {  
        
      }
      showWeatherResults(weather) {
        let renderedSection;
        let p1;
        if (p1) {
          p1.innerHTML = `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
        } else {
          renderedSection = document.querySelector('#renderedContent');
          p1 = document.createElement("p");
          renderedSection.appendChild(p1);
          p1.innerHTML += `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
          this.clearInput();
        }
      }
      clearInput() {
        let input = document.querySelector('input');
        input.value = '';
      }
    }
    
    <h1>Enter your zipcode here</h1>
    <form>
      <input id="zipInput" type="text">
      <button id="zipButton">Submit</button>
    </form>
    <section id="renderedContent"></section>
    
    const weatherApp = new WeatherApp;
    const ui = new UI;
    const zipButton = document.querySelector('#zipButton');
    
    // Event listeners
    zipButton.addEventListener('click', async (e) => {
      e.preventDefault();
      const weatherResult = await weatherApp.getWeather()
      ui.showWeatherResults(weatherResult);
    });
    
    相关HTML:

    class UI {
      constructor() {  
        
      }
      showWeatherResults(weather) {
        let renderedSection;
        let p1;
        if (p1) {
          p1.innerHTML = `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
        } else {
          renderedSection = document.querySelector('#renderedContent');
          p1 = document.createElement("p");
          renderedSection.appendChild(p1);
          p1.innerHTML += `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
          this.clearInput();
        }
      }
      clearInput() {
        let input = document.querySelector('input');
        input.value = '';
      }
    }
    
    <h1>Enter your zipcode here</h1>
    <form>
      <input id="zipInput" type="text">
      <button id="zipButton">Submit</button>
    </form>
    <section id="renderedContent"></section>
    
    const weatherApp = new WeatherApp;
    const ui = new UI;
    const zipButton = document.querySelector('#zipButton');
    
    // Event listeners
    zipButton.addEventListener('click', async (e) => {
      e.preventDefault();
      const weatherResult = await weatherApp.getWeather()
      ui.showWeatherResults(weatherResult);
    });
    
    我还有一个名为weather.js的额外JavaScript文件,用于处理API调用,但似乎没有必要添加它

    更新: 多亏了大家的帮助,我有了更干净的代码,它完全符合我的要求,现在我开始更好地理解state&关键字this

        class UI {
      constructor() {  
        this.renderedSection = document.querySelector('#renderedContent');
        this.p1 = document.createElement("p");
      }
      showWeatherResults(weather) {      
          const { renderedSection, p1, clearInput } = this;
          renderedSection.appendChild(p1);
          p1.innerHTML = `The tempature is currently: ${kelvinToFaren(weather.main.temp)}, with a high of ${kelvinToFaren(weather.main.temp_max)} and a low of ${kelvinToFaren(weather.main.temp_min)}`;
          clearInput();
      }
      clearInput() {
        let input = document.querySelector('input');
        input.value = '';
      }
    }
    

    在函数中声明的变量在函数调用之间不保存其值

    let p1声明变量。它没有给它赋值。在
    else
    块中为它指定一个之前,它始终是
    未定义的

    您需要:

    • 创建变量时在DOM中搜索节点
    • 在函数外部声明变量

    ES5?这里有很多ES6+功能。对不起,我是说ES6,谢谢!此外,问题与代码运行的JS版本完全无关。您的逻辑有问题-调用方法时,总是以
    p1
    作为
    undefined
    开始。即使重新分配它,下次调用它时也会创建一个完全独立的变量。您不会保留上一次执行的状态。
    let p1;如果(p1)
    那么,这永远是错误的。我想你是想在通话之间保持p1的状态。在这种情况下,请尝试将
    p1
    替换为
    this.p1
    ,并使其成为类的成员(对象的属性或任何正确的术语)。谢谢!我尝试在构造函数中声明它,但没有成功。我必须在全局范围内声明它吗?必须在您可以访问它的范围内声明它。您可以将其作为对象实例的属性而不是变量。@bbacs您可能希望将其作为实例属性。这是对象状态的一部分。我想你只需要说
    this.p1
    ,而不是
    p1
    。这非常有用。我需要了解状态对象和实例属性。泰!