parseInt 在某些严格比较中失败(stringParsedToInteger === 3; // returns undefined)

parseInt fails in certain strict comparisons ( stringParsedToInteger === 3; // returns undefined)

只是好奇:

如果我使用比较运算符 ==.

将数字字符串(例如“10”)与整数 (10) 进行比较,则我的代码有效

但是如果我使用 parseInt() 将字符串转换为整数并使用严格比较运算符 === 与整数进行比较,它会失败 - 不会立即 - 一旦你开始弄乱参数(select 菜单)。

(time == 5).

中一样,没有 parseInt() 和使用比较运算符,相同的代码将按预期工作

失败的代码:

  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>

在侦听器内部,当你这样做时

prodTime = e.target.value

这会检索更改后的值,但 HTMLElement 的 .value 将始终是一个字符串。因此,当您使用 findStartCost(prodTime) 将该字符串传递给 findStartCost 时,您的条件是:

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 变量,您可以 return 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>