parseInt завершается с ошибкой при определенных строгих сравнениях (stringParsedToInteger === 3; // возвращает неопределенное значение) - PullRequest
0 голосов
/ 07 марта 2020

Просто любопытно:

Мой код работает, если я сравниваю числовую строку (например, '10') с целым числом (10), используя оператор сравнения ==.

Но если Я преобразую строку в целое число с parseInt() и сравниваю с целыми числами с помощью оператора строгого сравнения ===, но не сразу - сразу после того, как вы начнете связываться с параметрами (выберите меню).

Тот же код будет работать должным образом без parseInt () и с операторами сравнения, как в (time == 5).

Код, который не работает:

  const productSelect = document.querySelector('#product')
  let productValue = document.querySelector('#product').value
  const prodTimeSelect = document.querySelector('#prodTime')
  let prodTime = parseInt(document.querySelector('#prodTime').value)
  const text = document.querySelector('.textoutput')
 
  // Find start cost
  let findStartCost = function(time) {
    if (time === 5) {
      return startCost = 2000
    } else if (time === 10) {
      return startCost = 1500
    } else if (time === 20) {
      return startCost = 1000
    }
  }
  
  text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`

  // Update text if product changes
  productSelect.addEventListener('change', function(e) {
    productValue = e.target.value
    text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`
  })

  // Update text if production time changes
  prodTimeSelect.addEventListener('change', function(e) {
    prodTime = e.target.value
    text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`
  })
<h3>Select Product</h3>
  <select id="product">
    <option value="1">Product 1</option>
    <option value="2">Product 2</option>
    <option value="3">Product 3</option>
    <option value="4">Product 4</option>
    <option value="5">Product 5</option>
  </select>

  <h3>Select production time</h3>
    <select id="prodTime">
      <option value="5" selected="selected">5 days</option>
      <option value="10">10 days</option>
      <option value="20">20 days</option>
    </select>

<p class="textoutput"></p>

Код, который работает:

const productSelect = document.querySelector('#product')
let productValue = document.querySelector('#product').value
const prodTimeSelect = document.querySelector('#prodTime')
let prodTime = document.querySelector('#prodTime').value
const text = document.querySelector('.textoutput')
 
// Find start cost
let findStartCost = function(time) {
  if (time == 5) {
   return startCost = 2000
  } else if (time == 10) {
   return startCost = 1500
  } else if (time == 20) {
   return startCost = 1000
 }
   }
  
text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`

// Update text if product changes
productSelect.addEventListener('change', function(e) {
 productValue = e.target.value
 text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`
  })

// Update text if production time changes
  prodTimeSelect.addEventListener('change', function(e) {
prodTime = e.target.value
text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`
  })
<h3>Select Product</h3>
      <select id="product">
        <option value="1">Product 1</option>
        <option value="2">Product 2</option>
        <option value="3">Product 3</option>
        <option value="4">Product 4</option>
        <option value="5">Product 5</option>
      </select>

      <h3>Select production time</h3>
        <select id="prodTime">
          <option value="5" selected="selected">5 days</option>
          <option value="10">10 days</option>
          <option value="20">20 days</option>
        </select>

    <p class="textoutput"></p>

1 Ответ

2 голосов
/ 07 марта 2020

Внутри слушателя, когда вы делаете

prodTime = e.target.value

Это возвращает измененное значение, но .value HTMLElement всегда будет строкой. Поэтому, когда вы передаете эту строку в findStartCost с findStartCost(prodTime), ваши условия:

if (time === 5) {
  return startCost = 2000
} else if (time === 10) {
  return startCost = 1500
} else if (time === 20) {
  return startCost = 1000
}

всегда не выполняются, потому что параметр time всегда является строкой, а не числом, поэтому он никогда не будет === к числу.

==, напротив, неявно преобразует свои операнды при сравнении, но это непредсказуемо, если вы не запомнили все различные возможности, поэтому его не следует использовать.

Используйте === и явно приведите значения самостоятельно:

  prodTimeSelect.addEventListener('change', function(e) {
    prodTime = Number(e.target.value);
    text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`;
  })

Кроме того, лучше не создавать неявно глобальные переменные - нет необходимости в переменной startCost, вы можете просто вернуть обычное значение в findStartCost.

Вы также можете сделать код менее повторяющимся, имея только одну функцию, которая извлекает значения из выборок и заполняет текст.

const productSelect = document.querySelector('#product');
const prodTimeSelect = document.querySelector('#prodTime');
const text = document.querySelector('.textoutput');

// Find start cost
let findStartCost = function(time) {
  if (time === 5) {
    return 2000;
  } else if (time === 10) {
    return 1500;
  } else if (time === 20) {
    return 1000;
  }
}

const updateText = () => {
  const productValue = productSelect.value;
  const prodTime = Number(prodTimeSelect.value);
  text.textContent = `The product number is #${productValue} and the production time is ${prodTime} days. Includes a start cost of ${findStartCost(prodTime)}.`;
};
updateText();
productSelect.addEventListener('change', updateText);
prodTimeSelect.addEventListener('change', updateText);
<h3>Select Product</h3>
<select id="product">
  <option value="1">Product 1</option>
  <option value="2">Product 2</option>
  <option value="3">Product 3</option>
  <option value="4">Product 4</option>
  <option value="5">Product 5</option>
</select>

<h3>Select production time</h3>
<select id="prodTime">
  <option value="5" selected="selected">5 days</option>
  <option value="10">10 days</option>
  <option value="20">20 days</option>
</select>

<p class="textoutput"></p>
...