javascript中判断原始类型最可靠方式是结合typeof和null特判;原始类型共7种:string、number、boolean、undefined、symbol、bigint、null;推荐函数准确覆盖全部且避免包装对象误判。

判断一个值是否为原始类型,核心是看它是否属于 JavaScript 的六种基本数据类型(也称原始值、primitive):string、number、boolean、undefined、symbol、null(注意:虽然 null 的 typeof 返回 "object",但它在语义和内存行为上仍是原始类型)。
用 typeof + 特殊处理识别原始类型
typeof 能准确识别除 null 外的所有原始类型:
-
typeof "hello"→"string" -
typeof 42→"number" -
typeof true→"boolean" -
typeof undefined→"undefined" -
typeof Symbol()→"symbol" -
typeof null→"object"(这是历史遗留 bug,需单独判断)
所以通用判断逻辑是:
function isPrimitive(val) {
return val === null || typeof val !== 'object';
}
这个表达式简洁有效:只要不是对象(包括数组、普通对象、函数、日期等),且排除了 undefined(它本身 typeof 就是 "undefined",也满足 typeof val !== 'object'),就属于原始类型。
为什么不能只靠 instanceof 或 constructor?
instanceof 和 .constructor 只对引用类型有意义,对原始值会失效:
-
"abc" instanceof String→false(字面量字符串不是 String 实例) -
(42).constructor === Number→true,但这种包装行为有隐式转换开销,且不可靠(如跨 iframe 时constructor可能不同) -
null和undefined没有constructor属性,直接访问会报错
深拷贝中识别原始类型的实际作用
在手写递归深拷贝时,识别原始类型决定是否“直接返回”而非继续递归:
- 原始值(如
123、"ok"、true)直接赋值即可,无需克隆 - 引用值(如对象、数组、函数)才需要开辟新内存、逐项复制
- 特别注意:
typeof function() {}是"function",它虽是引用类型,但有些深拷贝策略选择跳过或浅复制(因函数通常不序列化)
补充:NaN 和 Infinity 属于 number 类型
它们是原始类型中的特殊数值:
-
typeof NaN→"number" -
typeof Infinity→"number" -
Number.isNaN(NaN)和val === Infinity可进一步区分,但不影响“它是原始类型”的判断
深拷贝时它们会被 JSON.stringify 静默转为 null,但这属于序列化限制,不改变其原始类型的本质。











