原始值与对象值的区别在于存储位置(栈存值、堆存地址)、可变性(原始值不可变、对象值可变)和比较逻辑(原始值比内容、对象值比地址),null是原始值但typeof返回"object"。

区分原始值和对象值,关键看三点:存储位置、可变性、比较逻辑。不是靠名字判断,而是看它在内存里怎么存、能不能改、相等是怎么定义的。
看存储方式:栈里存值,堆里存地址
原始值(undefined、null、boolean、number、string、symbol、bigint)直接存在栈内存里,变量里放的就是实实在在的值;对象值(包括 Object、Array、Function、Date、RegExp、Map、Set 等)本身存在堆内存,变量里只存一个指向它的地址。
- 比如
let a = 100,a 中就是数字 100;再写let b = a,b 拿到的是新拷贝的 100,改 b 不影响 a - 而
let obj1 = {x: 1},obj1 存的是堆中那个对象的地址;let obj2 = obj1,obj2 得到的是同一个地址,改obj2.x,obj1.x也会变
看能否修改:原始值不可变,对象值可变
原始值一旦创建就不能被修改——所有看似“改变字符串”的操作(如 str.toUpperCase()、num.toFixed(2)),实际都是返回一个新值,原值毫发无伤。
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
-
let s = "hello"; s = s + " world"—— 不是改了 "hello",而是让 s 指向新字符串 "hello world" -
let arr = [1, 2]; arr.push(3)—— 数组本身被修改了,长度、内容都变了,arr 还是指向原来那个对象
看相等判断:值相等 vs 地址相等
两个原始值用 === 比较,只要内容一样就为 true;两个对象用 === 比较,只有它们指向堆中同一块内存才为 true。
-
"abc" === "abc"→ true(值相同) -
[1,2] === [1,2]→ false(两个独立数组,地址不同) -
let a = {}; let b = a; a === b→ true(同一对象,地址相同)
看 typeof 和判空:null 是个特例
typeof null 返回 "object",这是历史遗留 bug,但它本质是原始值。判断是否为真正对象,不能只靠 typeof:
- 先排除
null:value !== null && typeof value === 'object' - 再区分数组和普通对象:
Array.isArray(value)或Object.prototype.toString.call(value) === '[object Array]' - 函数虽是对象,但
typeof fn === 'function'是可靠写法
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










