404 Not Found

404 Not Found


nginx

JavaScript Utility Methods

We've covered type conversions — now let's learn a batch of utility methods you'll use every day. Think of them as a Swiss army knife — each one is simple, but you'll miss any one of them when you need it.

📖 Summary

parseInt and parseFloat

Parse numbers from the beginning of a string, stopping at the first non-numeric character:

HTML
<script>
console.log(parseInt("42px"));      // 42
console.log(parseInt("3.14"));      // 3 (integer part only)
console.log(parseFloat("3.14"));    // 3.14
console.log(parseFloat("3.14abc")); // 3.14
console.log(parseInt("abc42"));     // NaN (doesn't start with a number)
</script>

The second argument of parseInt specifies the radix:

HTML
<script>
console.log(parseInt("FF", 16));  // 255 (hexadecimal)
console.log(parseInt("10", 2));   // 2 (binary)
</script>

Pitfall: Without a radix, strings starting with 0x are parsed as hexadecimal. Always pass 10 as the second argument.

isNaN vs Number.isNaN

Method Behavior
isNaN(value) Converts to number first, then checks if it's NaN
Number.isNaN(value) Strictly checks if the value is NaN (no conversion)
HTML
<script>
console.log(isNaN("hello"));         // true (Number("hello") → NaN, then true)
console.log(Number.isNaN("hello"));  // false ("hello" itself is not NaN)
console.log(isNaN(undefined));       // true
console.log(Number.isNaN(undefined));// false
</script>

Conclusion: Use Number.isNaN() — it won't silently coerce types.

toFixed

Controls decimal places, returns a string:

HTML
<script>
console.log((3.14159).toFixed(2));  // "3.14"
console.log((3.1).toFixed(4));      // "3.1000" (padded with zeros)
console.log((3.145).toFixed(2));    // "3.14" or "3.15" (floating-point precision issue, rounding not guaranteed)
</script>

Note that toFixed returns a string — use Number() to convert it back for calculations.

toString

Converts a number to a string, with optional radix support:

HTML
<script>
console.log((255).toString());      // "255"
console.log((255).toString(16));    // "ff"
console.log((8).toString(2));       // "1000"
console.log((100).toString(8));     // "144"
</script>

Booleans and arrays also have toString:

HTML
<script>
console.log(true.toString());       // "true"
console.log([1,2,3].toString());    // "1,2,3"
</script>

Number.isInteger

Checks whether a value is an integer:

HTML
<script>
console.log(Number.isInteger(5));      // true
console.log(Number.isInteger(5.0));    // true (5.0 is just 5)
console.log(Number.isInteger(5.5));    // false
console.log(Number.isInteger("5"));    // false (a string is not an integer)
console.log(Number.isInteger(NaN));    // false
</script>

Math.trunc and Math.sign

Math.trunc simply chops off the decimal part (no rounding):

HTML
<script>
console.log(Math.trunc(4.9));    // 4
console.log(Math.trunc(-4.9));   // -4
console.log(Math.trunc(4.1));    // 4
</script>

Math.sign returns the sign of a number:

HTML
<script>
console.log(Math.sign(5));       // 1
console.log(Math.sign(-5));      // -1
console.log(Math.sign(0));       // 0
console.log(Math.sign(-0));      // -0
console.log(Math.sign(NaN));     // NaN
</script>

Limitations of typeof

typeof usually works for type checking, but there are a few classic gotchas:

HTML
<script>
console.log(typeof 42);           // "number"  ✅
console.log(typeof "hello");      // "string"  ✅
console.log(typeof true);         // "boolean" ✅
console.log(typeof undefined);    // "undefined" ✅
console.log(typeof null);         // "object"  ❌ This is a historical bug!
console.log(typeof []);           // "object"  ❌ Arrays are also objects
console.log(typeof {});           // "object"  ✅
console.log(typeof function(){}); // "function" ✅
</script>

typeof null === "object" is a "veteran bug" in JavaScript — it's been around since 1995 and can never be fixed. Use value === null to check for null. Use Array.isArray() to check for arrays.


Example: Price Calculator

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Price Calculator</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .calc { max-width: 440px; margin: 16px auto; padding: 24px; background: #f9f9f9; border-radius: 12px; }
    .row { margin: 12px 0; display: flex; align-items: center; gap: 10px; }
    label { width: 80px; font-weight: bold; }
    input { padding: 8px 12px; font-size: 16px; border: 2px solid #ccc; border-radius: 6px; flex: 1; }
    button { padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; background: #4a90d9; color: #fff; width: 100%; margin-top: 8px; }
    button:hover { background: #357abd; }
    .result { margin-top: 16px; padding: 16px; background: #fff; border-radius: 8px; border: 2px solid #5cb85c; }
    .result div { margin: 4px 0; }
    .total { font-size: 22px; font-weight: bold; color: #d9534f; }
  </style>
</head>
<body>
  <h2 style="text-align:center;">Price Calculator</h2>
  <div class="calc">
    <div class="row">
      <label>Unit Price:</label>
      <input type="text" id="price" value="29.90" placeholder="e.g. 29.90" />
    </div>
    <div class="row">
      <label>Quantity:</label>
      <input type="text" id="qty" value="3" placeholder="e.g. 3" />
    </div>
    <div class="row">
      <label>Discount:</label>
      <input type="text" id="discount" value="0.85" placeholder="e.g. 0.85 (15% off)" />
    </div>
    <button id="calc">Calculate</button>
    <div class="result" id="result" style="display:none;"></div>
  </div>
  <script>
    document.getElementById("calc").addEventListener("click", function() {
      const priceStr = document.getElementById("price").value.trim();
      const qtyStr = document.getElementById("qty").value.trim();
      const discountStr = document.getElementById("discount").value.trim();

      const price = parseFloat(priceStr);
      const qty = parseInt(qtyStr, 10);
      const discount = parseFloat(discountStr);

      if (Number.isNaN(price) || price <= 0) {
        alert("Invalid unit price! Please enter a positive number.");
        return;
      }
      if (Number.isNaN(qty) || qty <= 0 || !Number.isInteger(qty)) {
        alert("Invalid quantity! Please enter a positive integer.");
        return;
      }
      if (Number.isNaN(discount) || discount <= 0 || discount > 1) {
        alert("Invalid discount! Please enter a decimal between 0 and 1.");
        return;
      }

      const subtotal = price * qty;
      const total = subtotal * discount;
      const saved = subtotal - total;

      document.getElementById("result").style.display = "block";
      document.getElementById("result").innerHTML = `
        <div>Unit Price: $${price.toFixed(2)}</div>
        <div>Quantity: ${qty}</div>
        <div>Subtotal: $${subtotal.toFixed(2)}</div>
        <div>Discount: ${(discount * 100).toFixed(0)}% off (-$${saved.toFixed(2)})</div>
        <div class="total">Total: $${total.toFixed(2)}</div>
      `;
    });
  </script>
</body>
</html>
▶ Try it Yourself

Example: Input Validation Tool

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Input Validation</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    .demo { max-width: 500px; margin: 16px auto; }
    .row { margin: 12px 0; display: flex; align-items: center; gap: 10px; }
    label { width: 80px; font-weight: bold; }
    input { padding: 8px 12px; font-size: 16px; border: 2px solid #ccc; border-radius: 6px; flex: 1; }
    input.valid { border-color: #5cb85c; background: #f0fff0; }
    input.invalid { border-color: #d9534f; background: #fff0f0; }
    .msg { font-size: 13px; margin-left: 90px; }
    .msg.valid { color: #5cb85c; }
    .msg.invalid { color: #d9534f; }
    .methods { margin-top: 20px; padding: 16px; background: #f5f5f5; border-radius: 8px; }
    .methods div { margin: 4px 0; font-family: monospace; font-size: 14px; }
  </style>
</head>
<body>
  <h2 style="text-align:center;">Input Validation Demo</h2>
  <div class="demo">
    <div class="row">
      <label>Age:</label>
      <input type="text" id="age" placeholder="Enter age" />
    </div>
    <div class="msg" id="ageMsg"></div>

    <div class="row">
      <label>Phone:</label>
      <input type="text" id="phone" placeholder="Enter phone number" />
    </div>
    <div class="msg" id="phoneMsg"></div>

    <div class="row">
      <label>Amount:</label>
      <input type="text" id="amount" placeholder="Enter amount" />
    </div>
    <div class="msg" id="amountMsg"></div>

    <div class="methods" id="methods"></div>
  </div>
  <script>
    function validateAge(value) {
      const num = parseInt(value, 10);
      if (value.trim() === "") return { valid: false, msg: "Cannot be empty" };
      if (Number.isNaN(num)) return { valid: false, msg: "Not a valid integer" };
      if (!Number.isInteger(Number(value))) return { valid: false, msg: "Age must be an integer" };
      if (num < 0 || num > 150) return { valid: false, msg: "Age range: 0–150" };
      return { valid: true, msg: `Valid — you are ${num} years old` };
    }

    function validatePhone(value) {
      const trimmed = value.trim();
      if (trimmed === "") return { valid: false, msg: "Cannot be empty" };
      if (!/^\d+$/.test(trimmed)) return { valid: false, msg: "Numbers only" };
      if (trimmed.length !== 11) return { valid: false, msg: "Phone number must be 11 digits" };
      return { valid: true, msg: "Format is correct" };
    }

    function validateAmount(value) {
      const num = parseFloat(value);
      if (value.trim() === "") return { valid: false, msg: "Cannot be empty" };
      if (Number.isNaN(num)) return { valid: false, msg: "Not a valid number" };
      if (num <= 0) return { valid: false, msg: "Amount must be greater than 0" };
      return { valid: true, msg: `Valid — amount $${num.toFixed(2)}` };
    }

    function setupValidation(inputId, msgId, validator) {
      const input = document.getElementById(inputId);
      const msg = document.getElementById(msgId);
      input.addEventListener("input", function() {
        const result = validator(input.value);
        input.className = result.valid ? "valid" : "invalid";
        msg.className = "msg " + (result.valid ? "valid" : "invalid");
        msg.textContent = result.msg;
        updateMethods();
      });
    }

    setupValidation("age", "ageMsg", validateAge);
    setupValidation("phone", "phoneMsg", validatePhone);
    setupValidation("amount", "amountMsg", validateAmount);

    function updateMethods() {
      const age = document.getElementById("age").value;
      const phone = document.getElementById("phone").value;
      const amount = document.getElementById("amount").value;
      document.getElementById("methods").innerHTML = `
        <strong>Utility Method Results:</strong>
        <div>parseInt("${age}", 10) → ${parseInt(age, 10)}</div>
        <div>Number.isNaN(parseInt("${age}")) → ${Number.isNaN(parseInt(age, 10))}</div>
        <div>parseFloat("${amount}") → ${parseFloat(amount)}</div>
        <div>typeof "${phone}" → "${typeof phone}"</div>
      `;
    }
  </script>
</body>
</html>
▶ Try it Yourself

Example: typeof and Type Checking

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>typeof Type Checking</title>
  <style>
    body { font-family: sans-serif; padding: 20px; }
    table { border-collapse: collapse; margin: 16px 0; width: 100%; max-width: 700px; }
    td, th { border: 1px solid #ddd; padding: 10px 14px; text-align: left; }
    th { background: #4a90d9; color: #fff; }
    .bug { background: #fff0f0; }
    .ok { background: #f0fff0; }
    .tip { background: #fff8e1; padding: 12px; border-radius: 6px; border-left: 4px solid #f0ad4e; margin: 16px 0; max-width: 700px; }
  </style>
</head>
<body>
  <h2>typeof Check for Each Type</h2>
  <div id="output"></div>
  <script>
    const values = [
      [42, "Number"],
      ["hello", "String"],
      [true, "Boolean"],
      [undefined, "undefined"],
      [null, "null ⚠️"],
      [[1,2,3], "Array ⚠️"],
      [{a:1}, "Object"],
      [function(){}, "Function"],
      [NaN, "NaN"],
      [Infinity, "Infinity"],
    ];

    const rows = values.map(([val, label]) => {
      const typeResult = typeof val;
      const isBug = (val === null && typeResult === "object") ||
                    (Array.isArray(val) && typeResult === "object");
      const correctWay = val === null ? "value === null" :
                         Array.isArray(val) ? "Array.isArray(value)" :
                         "typeof is fine";
      return `<tr class="${isBug ? 'bug' : 'ok'}">
        <td>${label}</td>
        <td><code>${JSON.stringify(val)}</code></td>
        <td><code>"${typeResult}"</code></td>
        <td>${isBug ? "❌ Inaccurate" : "✅ Correct"}</td>
        <td>${isBug ? correctWay : "—"}</td>
      </tr>`;
    });

    document.getElementById("output").innerHTML = `
      <table>
        <tr><th>Expected Type</th><th>Value</th><th>typeof Result</th><th>Accurate?</th><th>Correct Approach</th></tr>
        ${rows.join("")}
      </table>
      <div class="tip">
        💡 Remember two edge cases: <code>typeof null</code> returns <code>"object"</code> (historical bug),
        and <code>typeof []</code> also returns <code>"object"</code> (arrays are not a distinct type).
        Use <code>=== null</code> for null checks, and <code>Array.isArray()</code> for array checks.
      </div>
    `;
  </script>
</body>
</html>
▶ Try it Yourself

❓ FAQ

Q Why might parseInt("08") return 0?
A In some older engines, strings starting with 0 were parsed as octal. "08" is invalid in octal, so it returned 0. Solution: always pass the second argument 10 — i.e. parseInt("08", 10)8.
Q Why doesn't toFixed guarantee rounding?
A Because floating-point numbers can't be represented exactly in binary. (0.1 + 0.2).toFixed(1) might give "0.3" or might not. For precise rounding, use Math.round(num * 100) / 100 before calling toFixed.
Q What's the difference between parseFloat and Number()?
A parseFloat("42px") returns 42 (parses from the start, stops at the first non-numeric character), while Number("42px") returns NaN (parses the whole string — any non-numeric character causes failure). Use parseFloat to extract numbers from mixed text; use Number() for strict validation.

📝 Exercises

  1. Write a function parseChineseNumber(str) that parses strings like "3.5元"3.5, "100人"100, "约200"200 (using parseFloat). Handle the case where plain text returns NaN.
  2. Write a function formatMoney(amount) that takes a number and returns a string with comma-separated thousands and two decimal places, e.g. 1234567.89"1,234,567.89" (hint: use toFixed and toString with array methods).
  3. Write a function getType(value)弥补 typeof 的缺陷:对 null 返回 null,对数组返回 array,其余情况返回 typeof 的结果。
100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏