简体   繁体   中英

Can't access global variables inside a function (Javascript)

I wrote a simple BMI calculator, but I seem to be unable to access global variables inside the function. If weight is only a number, everything is okay--but when I want to get this element with Javascript, it doesn't work. When those variables are inside a function, everything works excellent. I know, hoisting, scope.. but why do variables with numbers work then?

Here is the code:

const height = parseInt(document.querySelector("#height").value);
const weight = parseInt(document.querySelector("#weight").value);

const results = document.querySelector("#results");

function bmiCalc() {
  if (height === "" || isNaN(height))
    results.innerHTML = "Invalid Height! Please use numbers";
  else if (weight === "" || isNaN(weight))
    results.innerHTML = "Invalid Weight! Please use numbers";
  else {
    const bmi = (weight / ((height * height) / 10000)).toFixed();
    results.innerHTML = bmi;
  }
}

const button = document.querySelector(".results__btn");

button.addEventListener("click", bmiCalc);

The reason is that, when the page loads, your global variables will read the input before anything is entered. Global variables are created when the page load and deleted when the window is closed. In your code, the global variables weight and height are being created and they are assigned a value with these two inputs(which is empty). So, when you click the button, the weight and height variables has the value of "". Instead of showing the evaluated result, it will show you the error message. In the other hands, when you put the variables inside the function, the variable will not be created unless you execute the function (in this case, it is the bmiCalc function). This is how it works:

  1. The button is clicked
  2. The variable gets created.
  3. The function evaluates the inputs.
  4. It displays the result when the conditions are met.
  5. The function ends.
  6. The variables gets deleted.

And, the same process happens over and over again.

that is because you are fetching the value before the user enters anything, because the input data is fetched once script starts running

You need to put a listener every time input change to get the actual value from it if you wanna declare it on global scope. If you put height and weight into bmiCalc() it's working because the function is called only when the button is pressed so it takes the actual values from inputs (the current value when the button is pressed).

It's simply because the values for height and weight are being set the moment the page finishes loading, and before the bmiCalc function is even defined, bound, and run. Since you would want to pull fresh values when you click the calculate button, you need to have the code that reads the fields inside the bmiCalc function, otherwise, you'll only get the values that were there on startup. So, the variables are able to be accessed, but they're empty because there was nothing to read.

If you want to define element getters outside the function, you could rewrite it this way:


const heightInput = document.querySelector("#height");
const weightInput = document.querySelector("#weight");
const results = document.querySelector("#results");

function bmiCalc() {
  const height = parseInt(heightInput.value);
  const weight = parseInt(weightInput.value);
  if (height === "" || isNaN(height))
    results.innerHTML = "Invalid Height! Please use numbers";
  else if (weight === "" || isNaN(weight))
    results.innerHTML = "Invalid Weight! Please use numbers";
  else {
    const bmi = (weight / ((height * height) / 10000)).toFixed();
    results.innerHTML = bmi;
  }
}

const button = document.querySelector(".results__btn");

button.addEventListener("click", bmiCalc);

What this does differently is it binds the input elements outside of the function, but then actually reads and parses their contents inside the function when it's called.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM