JavaScript: 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.

1. Essential Utility Methods

(1) 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.

(2) 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.

(3) 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.

(4) 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>

(5) 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>

(6) 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>

(7) 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 📖 Display only
<!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>
71 logic lines (exceeds 40-line limit, display only)

▶ Example: Input Validation Tool

HTML 📖 Display only
<!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>
92 logic lines (exceeds 40-line limit, display only)

▶ Example: typeof and Type Checking

HTML 📖 Display only
<!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>
60 logic lines (exceeds 40-line limit, display only)

❓ FAQ

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.

📖 Summary

📝 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 🦄。
Web-Tutorial.com

Web-Tutorial Tech Team

A team of developers maintaining programming tutorials. Each tutorial is written and reviewed by developers with expertise in that field. We work to keep our content accurate and reliable — if you spot an issue, please let us know.

100%

🙏 帮我们做得更好

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

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