404 Not Found

404 Not Found


nginx

JavaScript Data Types

Data types determine what operations you can perform — numbers support arithmetic, strings support concatenation, booleans support conditionals. Understanding types helps you avoid JS's most classic pitfalls.

JS Data Types

JavaScript has 8 data types, divided into primitives and reference types:

Primitives (7 types): String, Number, BigInt, Boolean, Undefined, Null, Symbol

Reference type (1 type): Object (arrays, functions, dates, etc. are all subtypes of Object)

Primitive data is stored in stack memory and copied by value during assignment. Reference type data is stored in heap memory and copied by reference (address) during assignment. This distinction will be covered in depth in later lessons.

The typeof Operator

typeof is an operator that checks data types and returns a string:

Value typeof Result
"hello" "string"
42 "number"
9007199254740991n "bigint"
true "boolean"
undefined "undefined"
null "object" (historical bug)
{ } "object"
function(){} "function"

Note: typeof null returns "object" — this is a historical bug from JS's inception that can never be fixed (changing it would break existing code). Just remember it.

String and Number Pitfalls

The + operator in JS serves two purposes: numeric addition and string concatenation. When one side of + is a string, JS converts the other value to a string as well:

This is one of JS's most classic pitfalls — every beginner falls for it. The fix: use Number() or parseInt() for explicit conversion before math operations.

null vs undefined

Both mean "no value," but they differ in intent:

Think of it this way: undefined is a new house with no furniture yet; null is when you deliberately moved all the furniture out.

Example: typeof with Various Types

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Data Types - typeof</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 600px; margin: 60px auto; }
    table { width: 100%; border-collapse: collapse; margin: 16px 0; }
    th, td { padding: 10px; text-align: left; border: 1px solid #ddd; }
    th { background: #2196F3; color: #fff; }
    button { margin-top: 12px; padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #2196F3; }
    #result { margin-top: 12px; padding: 16px; background: #f5f5f5; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; white-space: pre; }
  </style>
</head>
<body>
  <h2>typeof Operator</h2>
  <button id="testBtn">Run typeof Test</button>
  <div id="result">Click the button to see typeof results</div>
  <script>
    document.getElementById("testBtn").onclick = function() {
      var a = "hello";
      var b = 42;
      var c = 9007199254740991n;
      var d = true;
      var e = undefined;
      var f = null;
      var g = {name: "John"};
      var h = [1, 2, 3];
      var i = function(){};
      var output = "";
      output += 'typeof "hello"  → "' + typeof a + '"\n';
      output += "typeof 42       → \"" + typeof b + '"\n';
      output += "typeof 9007199254740991n → \"" + typeof c + '"\n';
      output += "typeof true     → \"" + typeof d + '"\n';
      output += "typeof undefined → \"" + typeof e + '"\n';
      output += "typeof null     → \"" + typeof f + '"  ⚠️ Historical bug!\n';
      output += "typeof {}       → \"" + typeof g + '"\n';
      output += "typeof []       → \"" + typeof h + '"  (arrays are also object)\n';
      output += 'typeof function → "' + typeof i + '"';
      document.getElementById("result").textContent = output;
    };
  </script>
</body>
</html>
▶ Try it Yourself

Example: String and Number Pitfalls

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Data Types - String vs Number Pitfall</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 550px; margin: 60px auto; }
    .trap { background: #fff3e0; padding: 12px; border-radius: 8px; color: #E65100; border-left: 4px solid #FF9800; margin: 12px 0; }
    .safe { background: #e8f5e9; padding: 12px; border-radius: 8px; color: #2E7D32; border-left: 4px solid #4CAF50; margin: 12px 0; }
    .row { display: flex; justify-content: space-between; padding: 10px 16px; border-bottom: 1px solid #eee; font-family: Consolas, monospace; }
    .row:last-child { border-bottom: none; }
    .result-box { background: #f5f5f5; border-radius: 8px; margin: 12px 0; overflow: hidden; }
    .label { color: #666; }
    .value { font-weight: bold; }
    .bad { color: #f44336; }
    .good { color: #4CAF50; }
    button { margin-top: 12px; padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #e91e63; }
  </style>
</head>
<body>
  <h2>String + Number Pitfall</h2>
  <p class="trap">⚠️ When + has a string on either side, JS concatenates instead of adding! "5"+3 gives "53", not 8</p>
  <button id="trapBtn">Run Pitfall Demo</button>
  <div class="result-box" id="trapResult">
    <div class="row"><span class="label">"5" + 3 =</span><span class="value" id="r1">?</span></div>
    <div class="row"><span class="label">5 + 3 =</span><span class="value" id="r2">?</span></div>
    <div class="row"><span class="label">"5" - 3 =</span><span class="value" id="r3">?</span></div>
    <div class="row"><span class="label">"5" * 3 =</span><span class="value" id="r4">?</span></div>
  </div>
  <p class="safe">✅ Fix: use Number() for explicit conversion before arithmetic</p>
  <button id="safeBtn" style="background:#4CAF50;">Run Safe Version</button>
  <div class="result-box" id="safeResult">
    <div class="row"><span class="label">Number("5") + 3 =</span><span class="value" id="s1">?</span></div>
  </div>
  <script>
    document.getElementById("trapBtn").onclick = function() {
      var r1 = "5" + 3;
      var r2 = 5 + 3;
      var r3 = "5" - 3;
      var r4 = "5" * 3;
      document.getElementById("r1").textContent = '"' + r1 + '"';
      document.getElementById("r1").className = "value bad";
      document.getElementById("r2").textContent = r2;
      document.getElementById("r2").className = "value good";
      document.getElementById("r3").textContent = r3;
      document.getElementById("r3").className = "value good";
      document.getElementById("r4").textContent = r4;
      document.getElementById("r4").className = "value good";
    };
    document.getElementById("safeBtn").onclick = function() {
      var s1 = Number("5") + 3;
      document.getElementById("s1").textContent = s1;
      document.getElementById("s1").className = "value good";
    };
  </script>
</body>
</html>
▶ Try it Yourself

Example: null vs undefined

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Data Types - null vs undefined</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 550px; margin: 60px auto; }
    .card { padding: 16px; border-radius: 8px; margin: 12px 0; }
    .undef { background: #e3f2fd; border-left: 4px solid #2196F3; }
    .nul { background: #f3e5f5; border-left: 4px solid #9C27B0; }
    .result { background: #f5f5f5; padding: 16px; border-radius: 8px; font-family: Consolas, monospace; line-height: 1.8; white-space: pre; margin: 12px 0; }
    button { padding: 10px 24px; font-size: 16px; border: none; border-radius: 6px; cursor: pointer; color: #fff; background: #9C27B0; margin: 6px; }
  </style>
</head>
<body>
  <h2>null vs undefined</h2>
  <div class="card undef">
    <strong>undefined</strong>: variable declared but not assigned, or property doesn't exist<br>
    Meaning: "no value given yet" — like a new house with no furniture
  </div>
  <div class="card nul">
    <strong>null</strong>: developer explicitly set it to empty<br>
    Meaning: "intentionally set to nothing" — you deliberately moved the furniture out
  </div>
  <button id="testBtn">Run Comparison Test</button>
  <div class="result" id="output">Click the button to see results</div>
  <script>
    document.getElementById("testBtn").onclick = function() {
      var a;
      var b = null;
      var c = {name: "John"};
      var output = "";
      output += "=== undefined cases ===\n";
      output += "var a;  → a = " + a + " (undefined)\n";
      output += "typeof a → \"" + typeof a + "\"\n";
      output += "c.age → " + c.age + " (non-existent property is also undefined)\n\n";
      output += "=== null cases ===\n";
      output += "var b = null;  → b = " + b + " (null)\n";
      output += "typeof b → \"" + typeof b + "\"  ⚠️ Historical bug\n\n";
      output += "=== Comparison ===\n";
      output += "null == undefined  → " + (null == undefined) + "  (loose equality)\n";
      output += "null === undefined → " + (null === undefined) + "  (strict inequality)\n";
      output += "typeof null  → \"object\"  (bug)\n";
      output += "typeof undefined → \"undefined\"  (correct)\n\n";
      output += "Conclusion: null === undefined is false\n";
      output += "They have different meanings and are not the same value under strict comparison";
      document.getElementById("output").textContent = output;
    };
  </script>
</body>
</html>
▶ Try it Yourself

Example: All Data Types at a Glance

HTML
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Data Types - Complete Overview</title>
  <style>
    body { font-family: Arial, sans-serif; max-width: 600px; margin: 60px auto; }
    .type-card { display: inline-block; width: 120px; padding: 16px; margin: 6px; border-radius: 10px; text-align: center; color: #fff; cursor: pointer; transition: transform 0.2s; }
    .type-card:hover { transform: scale(1.08); }
    .type-card h3 { margin: 0 0 4px; font-size: 14px; opacity: 0.9; }
    .type-card p { margin: 0; font-size: 12px; font-family: Consolas, monospace; }
    .string { background: #4CAF50; }
    .number { background: #2196F3; }
    .bigint { background: #e91e63; }
    .boolean { background: #FF9800; }
    .undef { background: #9E9E9E; }
    .nul { background: #795548; }
    .symbol { background: #00BCD4; }
    .object { background: #9C27B0; }
    #detail { margin-top: 20px; padding: 20px; background: #f5f5f5; border-radius: 8px; font-size: 16px; line-height: 1.8; display: none; }
  </style>
</head>
<body>
  <h2>JS 8 Data Types</h2>
  <div class="type-card string" onclick="showDetail('string')"><h3>String</h3><p>"hello"</p></div>
  <div class="type-card number" onclick="showDetail('number')"><h3>Number</h3><p>42</p></div>
  <div class="type-card bigint" onclick="showDetail('bigint')"><h3>BigInt</h3><p>900n</p></div>
  <div class="type-card boolean" onclick="showDetail('boolean')"><h3>Boolean</h3><p>true</p></div>
  <div class="type-card undef" onclick="showDetail('undefined')"><h3>Undefined</h3><p>undefined</p></div>
  <div class="type-card nul" onclick="showDetail('null')"><h3>Null</h3><p>null</p></div>
  <div class="type-card symbol" onclick="showDetail('symbol')"><h3>Symbol</h3><p>Symbol()</p></div>
  <div class="type-card object" onclick="showDetail('object')"><h3>Object</h3><p>{key:"val"}</p></div>
  <div id="detail"></div>
  <script>
    function showDetail(type) {
      var detailEl = document.getElementById("detail");
      detailEl.style.display = "block";
      var info = {
        "string": "String\nText wrapped in quotes: \"hello\", 'world'\ntypeof → \"string\"\nCan be concatenated with +",
        "number": "Number\nIntegers and decimals: 42, 3.14, -7\nSpecial values: Infinity, -Infinity, NaN\ntypeof → \"number\"",
        "bigint": "BigInt\nRepresents integers beyond Number's safe range\nSyntax: add n after the number, e.g. 9007199254740991n\ntypeof → \"bigint\"",
        "boolean": "Boolean\nOnly two values: true and false\nCommonly used in conditionals\ntypeof → \"boolean\"",
        "undefined": "Undefined\nDefault value for declared but unassigned variables\ntypeof → \"undefined\"\nMeans \"no value yet\"",
        "null": "Null\nDeveloper explicitly sets it to \"empty\"\ntypeof → \"object\" (historical bug!)\nnull === undefined is false",
        "symbol": "Symbol\nAdded in ES6, creates unique identifiers\nEvery Symbol() is different\ntypeof → \"symbol\"\nCommonly used as object property keys",
        "object": "Object\nReference type, stores key-value pairs\nArrays [], functions, and dates are all objects\ntypeof → \"object\""
      };
      detailEl.textContent = info[type];
    }
  </script>
</body>
</html>
▶ Try it Yourself

📖 Summary

  1. JS has 8 data types: 7 primitives + 1 reference type (Object)
  2. The typeof operator checks types, but typeof null returns "object" — a historical bug
  3. + concatenates when a string is involved — "5" + 3 gives "53", not 8
  4. null means "intentionally empty"; undefined means "no value yet" — they are not strictly equal
  5. Use Number() or parseInt() for explicit conversion before math operations to avoid implicit coercion pitfalls
  6. Arrays [] also return "object" from typeof — use Array.isArray() to distinguish arrays from objects

❓ FAQ

Q Why does typeof null return "object"?
A This is a historical bug from JS's first version. Back then, JS used low bits to identify types, and null had all zero low bits — the same as the object identifier — so it was misclassified. They tried to fix it later, but changing it would break too much existing code, so the bug became permanent. It's like a building with a crooked foundation — too many people live there to tear it down.
Q How do I check if a value is an array vs a plain object?
A typeof returns "object" for both arrays and objects, so it can't distinguish them. The correct approach is Array.isArray() — for example, Array.isArray([1,2]) returns true, while Array.isArray({}) returns false.
Q What type is NaN?
A NaN (Not a Number) has typeof NaN returning "number". Even stranger, NaN === NaN returns false — it's not even equal to itself. Use isNaN() or Number.isNaN() to check for NaN.

📝 Exercises

  1. Basic: Declare 6 variables for 6 primitive types (String, Number, Boolean, Undefined, Null, Object), use typeof on each, and display the results on the page.
  2. Intermediate: Create a page with an input field. When the user enters any value, JS detects its type using typeof and displays the result. Try entering numbers, strings, true, null, etc., and observe typeof's output.
  3. Challenge: Create a "Type Trap Quiz" page with 5 multiple-choice questions testing type coercion knowledge, such as what "1" + 2 equals, whether null == undefined is true or false, etc. Show correct/incorrect feedback with explanations when the user clicks an option.
100%

🙏 帮我们做得更好

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

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