【JavaScript】🔍 变量变形记:JavaScript 数据类型的 8 种分身术!

127 阅读4分钟

🌈 JavaScript 中的数据类型大揭秘!

JavaScript 有 8种内置类型StringNumberBooleannullundefinedSymbolBigIntObject
其中除了 Object 是引用类型,其他都叫 原始数据类型(基本类型)。
注意哦:变量本身没有类型,值才有!同一个变量可以随时“变身”存不同类型的值~
想知道值的类型?用 typeof 运算符就能查看啦!它会返回类型的字符串描述。

✨ 原始数据类型(Primitive Types)

1️⃣ 字符串(String)

字符串像只读的字符数组:有 length,也能用索引取值 [0]。但!字符串不可变,数组可变。试试就知道:

let s = "foo";
let arr = ["f", "o", "o"];

s[0] = "a"; // ❌ 悄悄失败,字符串不变!
arr[0] = "a"; // ✅ 数组元素被修改

console.log(s); // "foo" 
console.log(arr); // ["a", "o", "o"]

字符串方法(如 .toUpperCase()不会修改原值,而是返回新字符串。数组方法(如 .reverse())会直接修改原数组。所以处理字符串时,常先转数组 → 操作 → 转回字符串,超方便!

let book = "Harry Potter";

// 字符串方法:返回新字符串
let loudBook = book.toUpperCase(); 
console.log(loudBook); // "HARRY POTTER" 
console.log(book); // "Harry Potter"(原值不变)

// 想反转?先变数组!
let reversed = book.split("").reverse().join("");
console.log(reversed); // "rettoP yrraH" 🪄

2️⃣ 数字(Number)

JavaScript 只有一种数字类型 Number,用 64位双精度浮点数(IEEE 754标准)表示所有数字(包括“整数”)。
这导致一些“魔法现象”✨:

console.log(1 + 1 === 2); // ✅ true
console.log(0.1 + 0.2 === 0.3); // ❌ false!实际是 0.30000000000000004

为什么?
计算机用二进制存小数,但 0.10.2 转二进制是无限循环小数,存储时会被“四舍五入”。两个近似值相加,结果就有微小误差啦!

🔍 小知识

  • 安全整数范围-2^53+12^53-1(即 Number.MIN_SAFE_INTEGER ~ Number.MAX_SAFE_INTEGER
  • 特殊数字
    • NaN(Not a Number):表示“无效数值”,连自己都不等于自己!用 isNaN() 检测它。
    • Infinity / -Infinity:超出数值范围的结果,比如 1 / 0

3️⃣ 布尔值(Boolean)

只有两个值:truefalse,专为逻辑判断而生!常用操作符:

运算符含义例子
&&逻辑与true && false → false
``逻辑或`truefalse → true `
!逻辑非!true → false
console.log(5 > 3 && 2 < 4); // ✅ true
console.log("cat" === "dog" || 100 > 99); // ✅ true(至少一个对)

4️⃣ 空值(null) & 未定义(undefined)

这对“双胞胎”容易让人懵圈😵‍💫:

  • undefined:变量声明了但没赋值(默认值)。
  • null主动赋的空值,表示“这里应该有值,但我故意设为空”。
let empty = null;    // 我定义的“空”
let mystery;         // 未赋值 → undefined

console.log(empty === mystery); // false!他俩不一样哦

5️⃣ Symbol(唯一标识符)

每个 Symbol 值都是独一无二的!即使描述相同,也不相等:

let key1 = Symbol("secret_key");
let key2 = Symbol("secret_key");
console.log(key1 === key2); // ❌ false

6️⃣ BigInt(大整数)

专治超大数字(超过安全整数范围)!加个 n 后缀就行:

let bigNum = 9007199254740991n; // 安全范围外的整数
console.log(bigNum + 1n); // 9007199254740992n ✅

🧩 引用数据类型(Object)

就是对象啦!包括普通对象、数组、函数等。特点是 存在堆内存中,变量保存的是它的“内存地址”。

// 对象:键值对集合
let person = {
  name: "小明",
  age: 18,
  hobbies: ["唱歌", "编程"],
  sayHi() {
    console.log("你好~我是" + this.name);
  }
};

person.sayHi(); // 输出:"你好~我是小明"

💾 数据是如何存储的?

JavaScript 引擎(如 V8)管理这些内存空间:

空间类型存什么?特点
栈空间基本类型值、引用类型的地址自动分配/释放,速度快
堆空间引用类型的实际数据(对象、数组等)动态分配,由垃圾回收管理

看个例子理解“引用传递”:

function updateAge(obj) {
  obj.age = 25;          // 修改了原对象的属性
  obj = { name: "小红" }; // obj 指向了新对象(不影响外部)
  return obj;
}

let p1 = { name: "小明", age: 20 };
let p2 = updateAge(p1);

console.log(p1); // { name: "小明", age: 25 }(age被改)
console.log(p2); // { name: "小红" } (新对象)

关键点

  1. 传对象时,传递的是地址副本(指针)。
  2. 函数内修改对象属性,会影响外部。
  3. 但如果让参数指向新对象,不会影响外部变量

🎭 JavaScript 是啥类型语言?

记住三个关键词:动态的、弱类型的、灵活的

  • 动态类型:变量类型运行时确定,可随时改变。
  • 弱类型:支持隐式类型转换(比如 "5" - 3 → 2)。
let chameleon = 10;         // 🦎 现在是数字
chameleon = "变身字符串!";  // 嗖~变成字符串
chameleon = [1, 2, 3];      // 又成了数组!

这种设计让 JS 写起来超灵活,但也需要小心类型转换的坑哦~ 🪤