JavaScript: JavaScript 数据类型

数据类型决定了数据能做什么操作——数字能加减,字符串能拼接,布尔能判断。搞清楚类型,才能避免 JS 最经典的那些坑。

1. JS 的数据类型

JavaScript 有 8 种数据类型,分为基本类型引用类型两大阵营:

基本类型(7种):String、Number、BigInt、Boolean、Undefined、Null、Symbol

引用类型(1种):Object(数组、函数、日期等都是 Object 的子类型)

基本类型的数据存在栈内存中,赋值时拷贝值;引用类型的数据存在堆内存中,赋值时拷贝引用(地址)。这个区别后续课程会深入讲。


▶ 示例

JAVASCRIPT
// 本节代码示例
const message = "你好,世界!";
console.log(message);
▶ 试一试

这是最简单的示例,后续章节会详细解释。## 2. typeof 运算符

typeof 是检测数据类型的运算符,返回一个字符串:

typeof 结果
"hello" "string"
42 "number"
9007199254740991n "bigint"
true "boolean"
undefined "undefined"
null "object" (历史bug)
{ } "object"
function(){} "function"

注意:typeof null 返回 "object"——这是 JS 诞生时的一个历史 bug,修不了了(改了会破坏老代码),记住就好。


3. 字符串和数字的陷阱

JS 中 + 运算符有两个用途:数字相加和字符串拼接。当 + 两边有字符串时,JS 会把另一个值也转成字符串来拼接:

这是 JS 最经典的陷阱之一,新手必踩。解决方法:做数学运算前用 Number()parseInt() 显式转换。


4. null vs undefined 的区别

这两个都表示"没有值",但含义不同:

打个比方:undefined 是新房还没搬家具,null 是你主动把家具搬走了。

▶ 示例:typeof 检测各种类型

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>JS 数据类型 - typeof</title>
  <style>
    body { font-family: "Microsoft YaHei", 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 运算符</h2>
  <button id="testBtn">运行 typeof 测试</button>
  <div id="result">点击按钮查看 typeof 结果</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: "张三"};
      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 + '"  ⚠️ 这是历史Bug!\n';
      output += "typeof {}       → \"" + typeof g + '"\n';
      output += "typeof []       → \"" + typeof h + '"  (数组也是object)\n';
      output += 'typeof function → "' + typeof i + '"';
      document.getElementById("result").textContent = output;
    };
  </script>
</body>
</html>
逻辑代码 43 行(超过 40 行限制,仅展示)

▶ 示例:字符串与数字的陷阱

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>JS 数据类型 - 字符串与数字陷阱</title>
  <style>
    body { font-family: "Microsoft YaHei", 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>字符串 + 数字的陷阱</h2>
  <p class="trap">⚠️ 当 + 两边有字符串时,JS 会拼接而非相加!"5"+3 得 "53" 而非 8</p>
  <button id="trapBtn">运行陷阱演示</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">✅ 解决方法:用 Number() 显式转换后再运算</p>
  <button id="safeBtn" style="background:#4CAF50;">运行安全写法</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>
逻辑代码 57 行(超过 40 行限制,仅展示)

▶ 示例:null 与 undefined 的区别

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>JS 数据类型 - null vs undefined</title>
  <style>
    body { font-family: "Microsoft YaHei", 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>:变量声明了但没赋值,或访问不存在的属性<br>
    含义:"还没给值" —— 像新房还没搬家具
  </div>
  <div class="card nul">
    <strong>null</strong>:开发者主动赋值为空<br>
    含义:"明确设为空" —— 你主动把家具搬走了
  </div>
  <button id="testBtn">运行对比测试</button>
  <div class="result" id="output">点击按钮查看结果</div>
  <script>
    document.getElementById("testBtn").onclick = function() {
      var a;
      var b = null;
      var c = {name: "张三"};
      var output = "";
      output += "=== undefined 情况 ===\n";
      output += "var a;  → a = " + a + " (undefined)\n";
      output += "typeof a → \"" + typeof a + "\"\n";
      output += "c.age → " + c.age + " (不存在的属性也是undefined)\n\n";
      output += "=== null 情况 ===\n";
      output += "var b = null;  → b = " + b + " (null)\n";
      output += "typeof b → \"" + typeof b + "\"  ⚠️ 历史Bug\n\n";
      output += "=== 区别对比 ===\n";
      output += "null == undefined  → " + (null == undefined) + "  (宽松相等)\n";
      output += "null === undefined → " + (null === undefined) + "  (严格不等)\n";
      output += "typeof null  → \"object\"  (bug)\n";
      output += "typeof undefined → \"undefined\"  (正确)\n\n";
      output += "结论:null === undefined 为 false\n";
      output += "它们含义不同,严格比较时不是同一个值";
      document.getElementById("output").textContent = output;
    };
  </script>
</body>
</html>
逻辑代码 51 行(超过 40 行限制,仅展示)

▶ 示例:各种数据类型一览

HTML 📖 仅展示
<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>JS 数据类型 - 完整一览</title>
  <style>
    body { font-family: "Microsoft YaHei", 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 种数据类型</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(字符串)\n用引号包裹的文本:\"hello\"、'world'\ntypeof → \"string\"\n可以用 + 拼接字符串",
        "number": "Number(数字)\n整数和小数:42、3.14、-7\n特殊值:Infinity、-Infinity、NaN\ntypeof → \"number\"",
        "bigint": "BigInt(大整数)\n表示超过 Number 安全范围的整数\n写法:数字后加 n,如 9007199254740991n\ntypeof → \"bigint\"",
        "boolean": "Boolean(布尔值)\n只有两个值:true 和 false\n常用于条件判断\ntypeof → \"boolean\"",
        "undefined": "Undefined(未定义)\n变量声明但未赋值时的默认值\ntypeof → \"undefined\"\n表示\"还没有值\"",
        "null": "Null(空值)\n开发者主动赋值表示\"空\"\ntypeof → \"object\" (历史Bug!)\nnull === undefined 为 false",
        "symbol": "Symbol(符号)\nES6 新增,创建唯一标识符\n每个 Symbol() 都不相同\ntypeof → \"symbol\"\n常用于对象属性键",
        "object": "Object(对象)\n引用类型,存储键值对集合\n数组 []、函数、日期都是 object\ntypeof → \"object\""
      };
      detailEl.textContent = info[type];
    }
  </script>
</body>
</html>
逻辑代码 51 行(超过 40 行限制,仅展示)

❓ 常见问题

Q 为什么 typeof null"object"
A 这是 JS 第一版的历史 bug。当时 JS 用低位标识类型,null 的低位全是 0,和 object 的标识一样,就误判了。后来想修,但改了会破坏大量现有代码,只好将错就错——就像一栋楼的地基歪了,住的人太多没法推倒重来。
Q 怎么判断一个值是数组而不是普通对象?
A typeof 对数组和对象都返回 "object",区分不了。正确方法是用 Array.isArray(),比如 Array.isArray([1,2]) 返回 trueArray.isArray({}) 返回 false
Q NaN 是什么类型?
A NaN(Not a Number)虽然名字叫"不是数字",但 typeof NaN 返回 "number"。更离谱的是 NaN === NaN 返回 false——自己都不等于自己。判断 NaN 要用 isNaN()Number.isNaN()

📖 小节

📝 作业

  1. 基础题:声明 6 个变量分别对应 6 种基本类型(String、Number、Boolean、Undefined、Null、Object),用 typeof 逐一检测并在页面上显示结果。
  2. 进阶题:创建一个页面,包含一个输入框,用户输入任意值后,JS 判断其类型(用 typeof)并显示在页面上。尝试输入数字、字符串、true、null 等,观察 typeof 的返回结果。
  3. 挑战题:创建一个"类型陷阱测试"页面,列出 5 道选择题测试用户对类型转换的理解,比如 "1" + 2 等于什么、null == undefined 是 true 还是 false 等,用户点击选项后显示对错和解释。
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

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

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